Blame modules/mount_nfs.c

Packit Service a4b2a9
/* ----------------------------------------------------------------------- *
Packit Service a4b2a9
 *   
Packit Service a4b2a9
 * mount_nfs.c - Module for Linux automountd to mount an NFS filesystem,
Packit Service a4b2a9
 *               with fallback to symlinking if the path is local
Packit Service a4b2a9
 *
Packit Service a4b2a9
 *   Copyright 1997 Transmeta Corporation - All Rights Reserved
Packit Service a4b2a9
 *   Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
Packit Service a4b2a9
 *
Packit Service a4b2a9
 *   This program is free software; you can redistribute it and/or modify
Packit Service a4b2a9
 *   it under the terms of the GNU General Public License as published by
Packit Service a4b2a9
 *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
Packit Service a4b2a9
 *   USA; either version 2 of the License, or (at your option) any later
Packit Service a4b2a9
 *   version; incorporated herein by reference.
Packit Service a4b2a9
 *
Packit Service a4b2a9
 * ----------------------------------------------------------------------- */
Packit Service a4b2a9
Packit Service a4b2a9
#include <stdio.h>
Packit Service a4b2a9
#include <malloc.h>
Packit Service a4b2a9
#include <netdb.h>
Packit Service a4b2a9
#include <stdlib.h>
Packit Service a4b2a9
#include <string.h>
Packit Service a4b2a9
#include <sys/param.h>
Packit Service a4b2a9
#include <sys/socket.h>
Packit Service a4b2a9
#include <sys/types.h>
Packit Service a4b2a9
#include <sys/stat.h>
Packit Service a4b2a9
#include <sys/vfs.h>
Packit Service a4b2a9
#include <netinet/in.h>
Packit Service a4b2a9
#include <linux/nfs.h>
Packit Service a4b2a9
#include <linux/nfs2.h>
Packit Service a4b2a9
#include <ctype.h>
Packit Service a4b2a9
Packit Service a4b2a9
#define MODULE_MOUNT
Packit Service a4b2a9
#include "automount.h"
Packit Service a4b2a9
#include "replicated.h"
Packit Service a4b2a9
Packit Service a4b2a9
#define MODPREFIX "mount(nfs): "
Packit Service a4b2a9
Packit Service a4b2a9
int mount_version = AUTOFS_MOUNT_VERSION;	/* Required by protocol */
Packit Service a4b2a9
Packit Service a4b2a9
static struct mount_mod *mount_bind = NULL;
Packit Service a4b2a9
static int init_ctr = 0;
Packit Service a4b2a9
Packit Service a4b2a9
int mount_init(void **context)
Packit Service a4b2a9
{
Packit Service a4b2a9
	/* Make sure we have the local mount method available */
Packit Service a4b2a9
	if (!mount_bind) {
Packit Service a4b2a9
		if ((mount_bind = open_mount("bind", MODPREFIX)))
Packit Service a4b2a9
			init_ctr++;
Packit Service a4b2a9
	} else
Packit Service a4b2a9
		init_ctr++;
Packit Service a4b2a9
Packit Service a4b2a9
	seed_random();
Packit Service a4b2a9
Packit Service a4b2a9
	return !mount_bind;
Packit Service a4b2a9
}
Packit Service a4b2a9
Packit Service a4b2a9
int mount_reinit(void **context)
Packit Service a4b2a9
{
Packit Service a4b2a9
	return 0;
Packit Service a4b2a9
}
Packit Service a4b2a9
Packit Service a4b2a9
int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len,
Packit Service a4b2a9
		const char *what, const char *fstype, const char *options,
Packit Service a4b2a9
		void *context)
Packit Service a4b2a9
{
Packit Service a4b2a9
	char fullpath[PATH_MAX];
Packit Service a4b2a9
	char buf[MAX_ERR_BUF];
Packit Service a4b2a9
	struct host *this, *hosts = NULL;
Packit Service a4b2a9
	unsigned int mount_default_proto, vers;
Packit Service a4b2a9
	char *nfsoptions = NULL;
Packit Service a4b2a9
	unsigned int flags = ap->flags &
Packit Service a4b2a9
			(MOUNT_FLAG_RANDOM_SELECT | MOUNT_FLAG_USE_WEIGHT_ONLY);
Packit Service a4b2a9
	int symlink = (*name != '/' && (ap->flags & MOUNT_FLAG_SYMLINK));
Packit Service a4b2a9
	int nobind = ap->flags & MOUNT_FLAG_NOBIND;
Packit Service a4b2a9
	int len, status, err, existed = 1;
Packit Service a4b2a9
	int nosymlink = 0;
Packit Service a4b2a9
	int port = -1;
Packit Service a4b2a9
	int ro = 0;            /* Set if mount bind should be read-only */
Packit Service a4b2a9
	int rdma = 0;
Packit Service 9c250c
	void (*mountlog)(unsigned int, const char*, ...) = &log_debug;
Packit Service a4b2a9
Packit Service a4b2a9
	if (ap->flags & MOUNT_FLAG_REMOUNT)
Packit Service a4b2a9
		return 0;
Packit Service a4b2a9
Packit Service 9c250c
	if (defaults_get_mount_verbose())
Packit Service 9c250c
		mountlog = &log_info;
Packit Service 9c250c
Packit Service 9c250c
	mountlog(ap->logopt,
Packit Service 9c250c
		 MODPREFIX "root=%s name=%s what=%s, fstype=%s, options=%s",
Packit Service 9c250c
		 root, name, what, fstype, options);
Packit Service a4b2a9
Packit Service a4b2a9
	mount_default_proto = defaults_get_mount_nfs_default_proto();
Packit Service 53a4e5
	vers = NFS_VERS_DEFAULT | NFS_PROTO_DEFAULT;
Packit Service a4b2a9
	if (strcmp(fstype, "nfs4") == 0)
Packit Service 53a4e5
		vers = NFS4_VERS_DEFAULT | TCP_SUPPORTED;
Packit Service a4b2a9
	else if (mount_default_proto == 4)
Packit Service 53a4e5
		vers = vers | NFS4_VERS_DEFAULT;
Packit Service a4b2a9
Packit Service a4b2a9
	/* Extract "nosymlink" pseudo-option which stops local filesystems
Packit Service a4b2a9
	 * from being symlinked.
Packit Service a4b2a9
	 *
Packit Service a4b2a9
	 * "nosymlink" is not used anymore. It is left for compatibility
Packit Service a4b2a9
	 * only (so we don't choke on it).
Packit Service a4b2a9
	 */
Packit Service a4b2a9
	if (options) {
Packit Service a4b2a9
		const char *comma;
Packit Service a4b2a9
		char *nfsp;
Packit Service a4b2a9
		int o_len = strlen(options) + 1;
Packit Service a4b2a9
Packit Service a4b2a9
		nfsp = nfsoptions = alloca(o_len + 1);
Packit Service a4b2a9
		if (!nfsoptions)
Packit Service a4b2a9
			return 1;
Packit Service a4b2a9
Packit Service a4b2a9
		memset(nfsoptions, '\0', o_len + 1);
Packit Service a4b2a9
Packit Service a4b2a9
		for (comma = options; *comma != '\0';) {
Packit Service a4b2a9
			const char *cp;
Packit Service a4b2a9
			const char *end;
Packit Service a4b2a9
Packit Service a4b2a9
			while (*comma == ',')
Packit Service a4b2a9
				comma++;
Packit Service a4b2a9
Packit Service a4b2a9
			/* Skip leading white space */
Packit Service a4b2a9
			while (*comma == ' ' || *comma == '\t')
Packit Service a4b2a9
				comma++;
Packit Service a4b2a9
Packit Service a4b2a9
			cp = comma;
Packit Service a4b2a9
			while (*comma != '\0' && *comma != ',')
Packit Service a4b2a9
				comma++;
Packit Service a4b2a9
Packit Service a4b2a9
			/* Skip trailing white space */
Packit Service a4b2a9
			end = comma - 1;
Packit Service a4b2a9
			while (*comma == ' ' || *comma == '\t')
Packit Service a4b2a9
				end--;
Packit Service a4b2a9
Packit Service a4b2a9
			o_len = end - cp + 1;
Packit Service a4b2a9
Packit Service a4b2a9
			if (_strncmp("proto=rdma", cp, o_len) == 0 ||
Packit Service a4b2a9
				   _strncmp("rdma", cp, o_len) == 0)
Packit Service a4b2a9
				rdma = 1;
Packit Service a4b2a9
Packit Service a4b2a9
			if (_strncmp("nosymlink", cp, o_len) == 0) {
Packit Service a4b2a9
				warn(ap->logopt, MODPREFIX
Packit Service a4b2a9
				     "the \"nosymlink\" option is depricated "
Packit Service a4b2a9
				     "and will soon be removed, "
Packit Service a4b2a9
				     "use the \"nobind\" option instead");
Packit Service a4b2a9
				nosymlink = 1;
Packit Service a4b2a9
			} else if (_strncmp("symlink", cp, o_len) == 0) {
Packit Service a4b2a9
				if (*name != '/')
Packit Service a4b2a9
					symlink = 1;
Packit Service a4b2a9
			} else if (_strncmp("nobind", cp, o_len) == 0) {
Packit Service a4b2a9
				nobind = 1;
Packit Service a4b2a9
			} else if (_strncmp("no-use-weight-only", cp, o_len) == 0) {
Packit Service a4b2a9
				flags &= ~MOUNT_FLAG_USE_WEIGHT_ONLY;
Packit Service a4b2a9
			} else if (_strncmp("use-weight-only", cp, o_len) == 0) {
Packit Service a4b2a9
				flags |= MOUNT_FLAG_USE_WEIGHT_ONLY;
Packit Service a4b2a9
			} else {
Packit Service a4b2a9
				/* Is any version of NFSv4 in the options */
Packit Service a4b2a9
				if (_strncmp("vers=4", cp, 6) == 0 ||
Packit Service a4b2a9
				    _strncmp("nfsvers=4", cp, 9) == 0)
Packit Service a4b2a9
					vers = NFS4_VERS_MASK | TCP_SUPPORTED;
Packit Service a4b2a9
				else if (_strncmp("vers=3", cp, o_len) == 0 ||
Packit Service a4b2a9
					 _strncmp("nfsvers=3", cp, o_len) == 0) {
Packit Service a4b2a9
					vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK);
Packit Service a4b2a9
					vers |= NFS3_REQUESTED;
Packit Service a4b2a9
				} else if (_strncmp("vers=2", cp, o_len) == 0 ||
Packit Service a4b2a9
					 _strncmp("nfsvers=2", cp, o_len) == 0) {
Packit Service a4b2a9
					vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK);
Packit Service a4b2a9
					vers |= NFS2_REQUESTED;
Packit Service a4b2a9
				} else if (strstr(cp, "port=") == cp &&
Packit Service a4b2a9
					 o_len - 5 < 25) {
Packit Service a4b2a9
					char optport[25];
Packit Service a4b2a9
Packit Service a4b2a9
					strncpy(optport, cp + 5, o_len - 5);
Packit Service a4b2a9
					optport[o_len - 5] = '\0';
Packit Service a4b2a9
					port = atoi(optport);
Packit Service a4b2a9
					if (port < 0)
Packit Service a4b2a9
						port = 0;
Packit Service a4b2a9
				} else if (_strncmp("proto=udp", cp, o_len) == 0 ||
Packit Service a4b2a9
					   _strncmp("udp", cp, o_len) == 0) {
Packit Service a4b2a9
					vers &= ~TCP_SUPPORTED;
Packit Service a4b2a9
				} else if (_strncmp("proto=udp6", cp, o_len) == 0 ||
Packit Service a4b2a9
					   _strncmp("udp6", cp, o_len) == 0) {
Packit Service a4b2a9
					vers &= ~TCP_SUPPORTED;
Packit Service a4b2a9
					vers |= UDP6_REQUESTED;
Packit Service a4b2a9
				} else if (_strncmp("proto=tcp", cp, o_len) == 0 ||
Packit Service a4b2a9
					   _strncmp("tcp", cp, o_len) == 0) {
Packit Service a4b2a9
					vers &= ~UDP_SUPPORTED;
Packit Service a4b2a9
				} else if (_strncmp("proto=tcp6", cp, o_len) == 0 ||
Packit Service a4b2a9
					   _strncmp("tcp6", cp, o_len) == 0) {
Packit Service a4b2a9
					vers &= ~UDP_SUPPORTED;
Packit Service a4b2a9
					vers |= TCP6_REQUESTED;
Packit Service a4b2a9
				}
Packit Service a4b2a9
				/* Check for options that also make sense
Packit Service a4b2a9
				   with bind mounts */
Packit Service a4b2a9
				else if (_strncmp("ro", cp, o_len) == 0)
Packit Service a4b2a9
					ro = 1;
Packit Service a4b2a9
				else if (_strncmp("rw", cp, o_len) == 0)
Packit Service a4b2a9
					ro = 0;
Packit Service a4b2a9
				/* and jump over trailing white space */
Packit Service a4b2a9
				memcpy(nfsp, cp, comma - cp + 1);
Packit Service a4b2a9
				nfsp += comma - cp + 1;
Packit Service a4b2a9
			}
Packit Service a4b2a9
		}
Packit Service a4b2a9
Packit Service a4b2a9
		/* In case both tcp and udp options were given */
Packit Service a4b2a9
		if ((vers & NFS_PROTO_MASK) == 0)
Packit Service a4b2a9
			vers |= NFS_PROTO_MASK;
Packit Service a4b2a9
Packit Service 9c250c
		mountlog(ap->logopt, MODPREFIX
Packit Service 9c250c
			 "nfs options=\"%s\", nobind=%d, nosymlink=%d, ro=%d",
Packit Service 9c250c
			 nfsoptions, nobind, nosymlink, ro);
Packit Service a4b2a9
	}
Packit Service a4b2a9
Packit Service a4b2a9
	if (!parse_location(ap->logopt, &hosts, what, flags)) {
Packit Service a4b2a9
		info(ap->logopt, MODPREFIX "no hosts available");
Packit Service a4b2a9
		return 1;
Packit Service a4b2a9
	}
Packit Service a4b2a9
	/*
Packit Service a4b2a9
	 * We can't probe protocol rdma so leave it to mount.nfs(8)
Packit Service a4b2a9
	 * and and suffer the delay if a server isn't available.
Packit Service a4b2a9
	 */
Packit Service a4b2a9
	if (rdma)
Packit Service a4b2a9
		goto dont_probe;
Packit Service a4b2a9
Packit Service a4b2a9
	/*
Packit Service a4b2a9
	 * If this is a singleton mount, and NFSv4 only hasn't been asked
Packit Service a4b2a9
	 * for, and the default NFS protocol is set to v4 in the autofs
Packit Service a4b2a9
	 * configuration only probe NFSv4 and let mount.nfs(8) do fallback
Packit Service a4b2a9
	 * to NFSv3 (if it can). If the NFSv4 probe fails then probe as
Packit Service a4b2a9
	 * normal.
Packit Service a4b2a9
	 *
Packit Service a4b2a9
	 * Note: some NFS servers consider it a protocol violation to use
Packit Service a4b2a9
	 * NFSv4 over UDP so if it has been requested in the mount options
Packit Service a4b2a9
	 * we can't use this at all.
Packit Service a4b2a9
	 */
Packit Service a4b2a9
	if ((hosts && !hosts->next) &&
Packit Service a4b2a9
	    mount_default_proto == 4 &&
Packit Service a4b2a9
	    (vers & NFS_VERS_MASK) != 0 &&
Packit Service a4b2a9
	    (vers & NFS4_VERS_MASK) != 0 &&
Packit Service a4b2a9
	    !(vers & UDP6_REQUESTED)) {
Packit Service a4b2a9
		unsigned int v4_probe_ok = 0;
Packit Service c687e0
		struct host *tmp = new_host(hosts->name, 0,
Packit Service a4b2a9
					    hosts->addr, hosts->addr_len,
Packit Service a4b2a9
					    hosts->proximity,
Packit Service a4b2a9
					    hosts->weight, hosts->options);
Packit Service a4b2a9
		if (tmp) {
Packit Service a4b2a9
			tmp->rr = hosts->rr;
Packit Service a4b2a9
			prune_host_list(ap->logopt, &tmp,
Packit Service a4b2a9
					NFS4_VERS_MASK|TCP_SUPPORTED, port);
Packit Service a4b2a9
			/* If probe succeeds just try the mount with host in hosts */
Packit Service a4b2a9
			if (tmp) {
Packit Service a4b2a9
				v4_probe_ok = 1;
Packit Service a4b2a9
				free_host_list(&tmp);
Packit Service a4b2a9
			}
Packit Service a4b2a9
		}
Packit Service a4b2a9
		if (!v4_probe_ok)
Packit Service a4b2a9
			prune_host_list(ap->logopt, &hosts, vers, port);
Packit Service a4b2a9
	} else {
Packit Service a4b2a9
		prune_host_list(ap->logopt, &hosts, vers, port);
Packit Service a4b2a9
	}
Packit Service a4b2a9
Packit Service a4b2a9
dont_probe:
Packit Service a4b2a9
	if (!hosts) {
Packit Service a4b2a9
		info(ap->logopt, MODPREFIX "no hosts available");
Packit Service a4b2a9
		return 1;
Packit Service a4b2a9
	}
Packit Service a4b2a9
Packit Service a4b2a9
	/* Construct and perhaps create mount point directory */
Packit Service a4b2a9
Packit Service a4b2a9
	/* Root offset of multi-mount */
Packit Service a4b2a9
	len = strlen(root);
Packit Service a4b2a9
	if (root[len - 1] == '/') {
Packit Service a4b2a9
		len = snprintf(fullpath, len, "%s", root);
Packit Service a4b2a9
	} else if (*name == '/') {
Packit Service a4b2a9
		len = sprintf(fullpath, "%s", root);
Packit Service a4b2a9
	} else {
Packit Service a4b2a9
		len = sprintf(fullpath, "%s/%s", root, name);
Packit Service a4b2a9
	}
Packit Service a4b2a9
	fullpath[len] = '\0';
Packit Service a4b2a9
Packit Service a4b2a9
	debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath);
Packit Service a4b2a9
Packit Service 15cf98
	status = mkdir_path(fullpath, mp_mode);
Packit Service a4b2a9
	if (status && errno != EEXIST) {
Packit Service a4b2a9
		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
Packit Service a4b2a9
		error(ap->logopt,
Packit Service a4b2a9
		      MODPREFIX "mkdir_path %s failed: %s", fullpath, estr);
Packit Service a4b2a9
		free_host_list(&hosts);
Packit Service a4b2a9
		return 1;
Packit Service a4b2a9
	}
Packit Service a4b2a9
Packit Service a4b2a9
	if (!status)
Packit Service a4b2a9
		existed = 0;
Packit Service a4b2a9
Packit Service a4b2a9
	this = hosts;
Packit Service a4b2a9
	while (this) {
Packit Service a4b2a9
		char *loc;
Packit Service a4b2a9
Packit Service a4b2a9
		/* Port option specified, don't try to bind */
Packit Service a4b2a9
		if (!(nosymlink || nobind) &&
Packit Service a4b2a9
		    this->proximity == PROXIMITY_LOCAL) {
Packit Service a4b2a9
			/* Local host -- do a "bind" */
Packit Service a4b2a9
			const char *bind_options;
Packit Service a4b2a9
Packit Service a4b2a9
			debug(ap->logopt,
Packit Service a4b2a9
			      MODPREFIX "%s is local, attempt bind mount",
Packit Service a4b2a9
			      name);
Packit Service a4b2a9
Packit Service a4b2a9
			bind_options = symlink ? "symlink" : ro ? "ro" : "";
Packit Service a4b2a9
Packit Service a4b2a9
			err = mount_bind->mount_mount(ap, root, name, name_len,
Packit Service a4b2a9
					       this->path, "bind", bind_options,
Packit Service a4b2a9
					       mount_bind->context);
Packit Service a4b2a9
Packit Service a4b2a9
			/* Success - we're done */
Packit Service a4b2a9
			if (!err) {
Packit Service a4b2a9
				free_host_list(&hosts);
Packit Service a4b2a9
				return 0;
Packit Service a4b2a9
			}
Packit Service a4b2a9
Packit Service a4b2a9
			/* Failed to update mtab, don't try any more */
Packit Service a4b2a9
			if (err == MNT_FORCE_FAIL)
Packit Service a4b2a9
				goto forced_fail;
Packit Service a4b2a9
Packit Service a4b2a9
			/* No hostname, can't be NFS */
Packit Service a4b2a9
			if (!this->name) {
Packit Service a4b2a9
				this = this->next;
Packit Service a4b2a9
				continue;
Packit Service a4b2a9
			}
Packit Service a4b2a9
		}
Packit Service a4b2a9
Packit Service a4b2a9
		/* Not a local host - do an NFS mount */
Packit Service a4b2a9
Packit Service a4b2a9
		if (this->rr && this->addr &&
Packit Service a4b2a9
		    !defaults_use_hostname_for_mounts()) {
Packit Service a4b2a9
			socklen_t len = INET6_ADDRSTRLEN;
Packit Service a4b2a9
			char n_buf[len + 1];
Packit Service a4b2a9
			const char *n_addr;
Packit Service 6acc18
Packit Service a4b2a9
			n_addr = get_addr_string(this->addr, n_buf, len);
Packit Service 6acc18
			if (!n_addr) {
Packit Service 6acc18
				char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
Packit Service 6acc18
				error(ap->logopt, "get_addr_string: %s", estr);
Packit Service 6acc18
				goto forced_fail;
Packit Service 6acc18
			}
Packit Service a4b2a9
			loc = malloc(strlen(n_addr) + strlen(this->path) + 4);
Packit Service a4b2a9
			if (!loc) {
Packit Service a4b2a9
				char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
Packit Service a4b2a9
				error(ap->logopt, "malloc: %s", estr);
Packit Service a4b2a9
				goto forced_fail;
Packit Service a4b2a9
			}
Packit Service a4b2a9
			if (this->addr->sa_family == AF_INET6) {
Packit Service a4b2a9
				strcpy(loc, "[");
Packit Service a4b2a9
				strcat(loc, n_addr);
Packit Service a4b2a9
				strcat(loc, "]");
Packit Service a4b2a9
			} else
Packit Service a4b2a9
				strcpy(loc, n_addr);
Packit Service a4b2a9
		} else {
Packit Service a4b2a9
			char *host = this->name ? this->name : "localhost";
Packit Service a4b2a9
			loc = malloc(strlen(host) + strlen(this->path) + 2);
Packit Service a4b2a9
			if (!loc) {
Packit Service a4b2a9
				char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
Packit Service a4b2a9
				error(ap->logopt, "malloc: %s", estr);
Packit Service a4b2a9
				goto forced_fail;
Packit Service a4b2a9
			}
Packit Service a4b2a9
			strcpy(loc, host);
Packit Service a4b2a9
		}
Packit Service a4b2a9
		strcat(loc, ":");
Packit Service a4b2a9
		strcat(loc, this->path);
Packit Service a4b2a9
Packit Service a4b2a9
		/* If this is a fallback from a bind mount failure
Packit Service a4b2a9
		 * check if the local NFS server is available to try
Packit Service a4b2a9
		 * and prevent lengthy mount failure waits.
Packit Service a4b2a9
		 */
Packit Service a4b2a9
		if (this->proximity == PROXIMITY_LOCAL) {
Packit Service a4b2a9
			char *host = this->name ? this->name : "localhost";
Packit Service a4b2a9
			int ret;
Packit Service a4b2a9
Packit Service a4b2a9
			ret = rpc_ping(host, port, vers, 2, 0, RPC_CLOSE_DEFAULT);
Packit Service a4b2a9
			if (ret <= 0)
Packit Service a4b2a9
				goto next;
Packit Service a4b2a9
		}
Packit Service a4b2a9
Packit Service a4b2a9
		if (nfsoptions && *nfsoptions) {
Packit Service 9c250c
			mountlog(ap->logopt,
Packit Service 9c250c
				 MODPREFIX "calling mount -t %s " SLOPPY
Packit Service 9c250c
				 "-o %s %s %s", fstype, nfsoptions, loc,
Packit Service 9c250c
				 fullpath);
Packit Service a4b2a9
Packit Service a4b2a9
			err = spawn_mount(ap->logopt,
Packit Service a4b2a9
					  "-t", fstype, SLOPPYOPT "-o",
Packit Service a4b2a9
					  nfsoptions, loc, fullpath, NULL);
Packit Service a4b2a9
		} else {
Packit Service 9c250c
			mountlog(ap->logopt,
Packit Service 9c250c
				 MODPREFIX "calling mount -t %s %s %s",
Packit Service 9c250c
				 fstype, loc, fullpath);
Packit Service a4b2a9
			err = spawn_mount(ap->logopt,
Packit Service a4b2a9
					  "-t", fstype, loc, fullpath, NULL);
Packit Service a4b2a9
		}
Packit Service a4b2a9
Packit Service a4b2a9
		if (!err) {
Packit Service a4b2a9
			debug(ap->logopt, MODPREFIX "mounted %s on %s", loc, fullpath);
Packit Service a4b2a9
			free(loc);
Packit Service a4b2a9
			free_host_list(&hosts);
Packit Service a4b2a9
			return 0;
Packit Service a4b2a9
		}
Packit Service a4b2a9
next:
Packit Service a4b2a9
		free(loc);
Packit Service a4b2a9
		this = this->next;
Packit Service a4b2a9
	}
Packit Service a4b2a9
Packit Service a4b2a9
forced_fail:
Packit Service a4b2a9
	free_host_list(&hosts);
Packit Service a4b2a9
Packit Service a4b2a9
	/* If we get here we've failed to complete the mount */
Packit Service a4b2a9
Packit Service a4b2a9
	info(ap->logopt, MODPREFIX "nfs: mount failure %s on %s", what, fullpath);
Packit Service a4b2a9
Packit Service a4b2a9
	if (ap->type != LKP_INDIRECT)
Packit Service a4b2a9
		return 1;
Packit Service a4b2a9
Packit Service a4b2a9
	if ((!(ap->flags & MOUNT_FLAG_GHOST) && name_len) || !existed)
Packit Service a4b2a9
		rmdir_path(ap, fullpath, ap->dev);
Packit Service a4b2a9
Packit Service a4b2a9
	return 1;
Packit Service a4b2a9
}
Packit Service a4b2a9
Packit Service a4b2a9
int mount_done(void *context)
Packit Service a4b2a9
{
Packit Service a4b2a9
	int rv = 0;
Packit Service a4b2a9
Packit Service a4b2a9
	if (--init_ctr == 0) {
Packit Service a4b2a9
		rv = close_mount(mount_bind);
Packit Service a4b2a9
		mount_bind = NULL;
Packit Service a4b2a9
	}
Packit Service a4b2a9
	return rv;
Packit Service a4b2a9
}