X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fmount.c;h=96b56973faeeb3731dcd98d74a51d216c5378fcf;hp=24ba394913a5f126eb56a54af780376cc69eecd8;hb=f014bb7f4dbdc45572849465a6410512abffa7ea;hpb=b960bca6e4f634bdcbcdd1d5638ab00db0851f8c diff --git a/utils/mount/mount.c b/utils/mount/mount.c index 24ba394..96b5697 100644 --- a/utils/mount/mount.c +++ b/utils/mount/mount.c @@ -26,12 +26,14 @@ #include #include #include +#include #include #include #include #include "fstab.h" #include "xcommon.h" +#include "nls.h" #include "mount_constants.h" #include "nfs_paths.h" @@ -39,8 +41,10 @@ #include "nfs4_mount.h" #include "nfsumount.h" #include "mount.h" +#include "error.h" char *progname; +int nfs_mount_data_version; int nomtab; int verbose; int sloppy; @@ -126,6 +130,51 @@ static const struct opt_map opt_map[] = { { NULL, 0, 0, 0 } }; +#define MAKE_VERSION(p,q,r) (65536 * (p) + 256 * (q) + (r)) + +int linux_version_code(void) +{ + struct utsname my_utsname; + int p, q, r; + + if (uname(&my_utsname) == 0) { + p = atoi(strtok(my_utsname.release, ".")); + q = atoi(strtok(NULL, ".")); + r = atoi(strtok(NULL, ".")); + return MAKE_VERSION(p,q,r); + } + return 0; +} + +/* + * Choose the version of the nfs_mount_data structure that is appropriate + * for the kernel that is doing the mount. + * + * NFS_MOUNT_VERSION: maximum version supported by these sources + * nfs_mount_data_version: maximum version supported by the running kernel + */ +static void discover_nfs_mount_data_version(void) +{ + int kernel_version = linux_version_code(); + + if (kernel_version) { + if (kernel_version < MAKE_VERSION(2, 1, 32)) + nfs_mount_data_version = 1; + else if (kernel_version < MAKE_VERSION(2, 2, 18)) + nfs_mount_data_version = 3; + else if (kernel_version < MAKE_VERSION(2, 3, 0)) + nfs_mount_data_version = 4; + else if (kernel_version < MAKE_VERSION(2, 3, 99)) + nfs_mount_data_version = 3; + else if (kernel_version < MAKE_VERSION(2, 6, 3)) + nfs_mount_data_version = 4; + else + nfs_mount_data_version = 6; + } + if (nfs_mount_data_version > NFS_MOUNT_VERSION) + nfs_mount_data_version = NFS_MOUNT_VERSION; +} + /* Try to build a canonical options string. */ static char * fix_opts_string (int flags, const char *extra_opts) { const struct opt_map *om; @@ -155,51 +204,54 @@ static char * fix_opts_string (int flags, const char *extra_opts) { return new_opts; } - -int add_mtab(char *fsname, char *mount_point, char *fstype, int flags, char *opts, int freq, int passno) +static int add_mtab(char *spec, char *mount_point, char *fstype, + int flags, char *opts, int freq, int pass) { struct mntent ment; FILE *mtab; + int result = EX_FILEIO; - ment.mnt_fsname = fsname; + ment.mnt_fsname = spec; ment.mnt_dir = mount_point; ment.mnt_type = fstype; ment.mnt_opts = fix_opts_string(flags, opts); - ment.mnt_freq = 0; - ment.mnt_passno= 0; + ment.mnt_freq = freq; + ment.mnt_passno = pass; - if(flags & MS_REMOUNT) { + if (flags & MS_REMOUNT) { update_mtab(ment.mnt_dir, &ment); return 0; } lock_mtab(); - if ((mtab = setmntent(MOUNTED, "a+")) == NULL) { + if ((mtab = setmntent(MOUNTED, "a+")) == NULL) { unlock_mtab(); - fprintf(stderr, "Can't open " MOUNTED); - return 1; + nfs_error(_("Can't open mtab: %s"), + strerror(errno)); + goto fail_unlock; } - if (addmntent(mtab, &ment) == 1) { - endmntent(mtab); - unlock_mtab(); - fprintf(stderr, "Can't write mount entry"); - return 1; + if (addmntent(mtab, &ment) == 1) { + nfs_error(_("Can't write mount entry to mtab: %s"), + strerror(errno)); + goto fail_close; } - if (fchmod(fileno(mtab), 0644) == -1) { - endmntent(mtab); - unlock_mtab(); - fprintf(stderr, "Can't set perms on " MOUNTED); - return 1; + if (fchmod(fileno(mtab), 0644) == -1) { + nfs_error(_("Can't set permissions on mtab: %s"), + strerror(errno)); + goto fail_close; } - endmntent(mtab); + result = 0; +fail_close: + endmntent(mtab); +fail_unlock: unlock_mtab(); - return 0; + return result; } int do_mount_syscall(char *spec, char *node, char *type, int flags, void *data) @@ -278,44 +330,20 @@ static void parse_opts (const char *options, int *flags, char **extra_opts) } } -static void mount_error(char *mntpnt, char *node) -{ - switch(errno) { - case ENOTDIR: - fprintf(stderr, "%s: mount point %s is not a directory\n", - progname, mntpnt); - break; - case EBUSY: - fprintf(stderr, "%s: %s is already mounted or busy\n", - progname, mntpnt); - break; - case ENOENT: - if (node) { - fprintf(stderr, "%s: %s failed, reason given by server: %s\n", - progname, node, strerror(errno)); - } else - fprintf(stderr, "%s: mount point %s does not exist\n", - progname, mntpnt); - break; - default: - fprintf(stderr, "%s: %s\n", progname, strerror(errno)); - } -} static int chk_mountpoint(char *mount_point) { struct stat sb; if (stat(mount_point, &sb) < 0){ - mount_error(mount_point, NULL); + mount_error(NULL, mount_point, errno); return 1; } if (S_ISDIR(sb.st_mode) == 0){ - errno = ENOTDIR; - mount_error(mount_point, NULL); + mount_error(NULL, mount_point, ENOTDIR); return 1; } if (access(mount_point, X_OK) < 0) { - mount_error(mount_point, NULL); + mount_error(NULL, mount_point, errno); return 1; } @@ -381,6 +409,8 @@ int main(int argc, char *argv[]) progname = basename(argv[0]); + discover_nfs_mount_data_version(); + if(!strncmp(progname, "umount", strlen("umount"))) { if(argc < 2) { umount_usage(); @@ -525,15 +555,15 @@ int main(int argc, char *argv[]) mount_opts); if (mnt_err) { - mount_error(mount_point, spec); + mount_error(spec, mount_point, errno); exit(EX_FAIL); } } if (!nomtab) - add_mtab(spec, mount_point, fs_type, - flags, extra_opts, 0, 0); + mnt_err = add_mtab(spec, mount_point, fs_type, flags, extra_opts, + 0, 0 /* these are always zero for NFS */ ); - return 0; + exit(mnt_err); }