17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5d1a180b0Smaheshvs * Common Development and Distribution License (the "License"). 6d1a180b0Smaheshvs * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*87c584d2Sbatschul * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 277c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 317c478bd9Sstevel@tonic-gate * The Regents of the University of California 327c478bd9Sstevel@tonic-gate * All Rights Reserved 337c478bd9Sstevel@tonic-gate * 347c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 357c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 367c478bd9Sstevel@tonic-gate * contributors. 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate /* 407c478bd9Sstevel@tonic-gate * mount 417c478bd9Sstevel@tonic-gate */ 427c478bd9Sstevel@tonic-gate #include <ctype.h> 437c478bd9Sstevel@tonic-gate #include <string.h> 447c478bd9Sstevel@tonic-gate #include <fcntl.h> 457c478bd9Sstevel@tonic-gate #include <signal.h> 467c478bd9Sstevel@tonic-gate #include <poll.h> 477c478bd9Sstevel@tonic-gate #include <sys/mkdev.h> 487c478bd9Sstevel@tonic-gate #include <sys/param.h> 497c478bd9Sstevel@tonic-gate #include <sys/types.h> 507c478bd9Sstevel@tonic-gate #include <sys/mntent.h> 517c478bd9Sstevel@tonic-gate #include <stdlib.h> 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate #define bcopy(f, t, n) memcpy(t, f, n) 547c478bd9Sstevel@tonic-gate #define bzero(s, n) memset(s, 0, n) 557c478bd9Sstevel@tonic-gate #define bcmp(s, d, n) memcmp(s, d, n) 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate #define index(s, r) strchr(s, r) 587c478bd9Sstevel@tonic-gate #define rindex(s, r) strrchr(s, r) 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate #include <errno.h> 617c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 627c478bd9Sstevel@tonic-gate #include <sys/stat.h> 637c478bd9Sstevel@tonic-gate #include <stdio.h> 647c478bd9Sstevel@tonic-gate #include <unistd.h> 657c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 667c478bd9Sstevel@tonic-gate #include <sys/mount.h> 677c478bd9Sstevel@tonic-gate #include <sys/mntio.h> 687c478bd9Sstevel@tonic-gate #include <sys/wait.h> 697c478bd9Sstevel@tonic-gate #include <sys/fstyp.h> 707c478bd9Sstevel@tonic-gate #include <sys/fsid.h> 717c478bd9Sstevel@tonic-gate #include <sys/vfstab.h> 727c478bd9Sstevel@tonic-gate #include <sys/filio.h> 737c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_fs.h> 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_mount.h> 767c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_filio.h> 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate #include <locale.h> 797c478bd9Sstevel@tonic-gate #include <fslib.h> 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate static int ro = 0; 827c478bd9Sstevel@tonic-gate static int largefiles = 0; /* flag - add default nolargefiles to mnttab */ 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate static int gflg = 0; 857c478bd9Sstevel@tonic-gate static int mflg = 0; 867c478bd9Sstevel@tonic-gate static int Oflg = 0; 877c478bd9Sstevel@tonic-gate static int qflg = 0; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate #define NAME_MAX 64 /* sizeof "fstype myname" */ 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate static int checkislog(char *); 927c478bd9Sstevel@tonic-gate static void disable_logging(char *, char *); 937c478bd9Sstevel@tonic-gate static int eatmntopt(struct mnttab *, char *); 947c478bd9Sstevel@tonic-gate static void enable_logging(char *, char *); 957c478bd9Sstevel@tonic-gate static void fixopts(struct mnttab *, char *); 967c478bd9Sstevel@tonic-gate static void mountfs(struct mnttab *); 977c478bd9Sstevel@tonic-gate static void replace_opts(char *, int, char *, char *); 987c478bd9Sstevel@tonic-gate static int replace_opts_dflt(char *, int, const char *, const char *); 997c478bd9Sstevel@tonic-gate static void rmopt(struct mnttab *, char *); 1007c478bd9Sstevel@tonic-gate static void rpterr(char *, char *); 1017c478bd9Sstevel@tonic-gate static void usage(void); 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate static char fstype[] = MNTTYPE_UFS; 1047c478bd9Sstevel@tonic-gate static char opts[MAX_MNTOPT_STR]; 1057c478bd9Sstevel@tonic-gate static char typename[NAME_MAX], *myname; 1067c478bd9Sstevel@tonic-gate static char *fop_subopts[] = { MNTOPT_ONERROR, NULL }; 1077c478bd9Sstevel@tonic-gate #define NOMATCH (-1) 1087c478bd9Sstevel@tonic-gate #define ONERROR (0) /* index within fop_subopts */ 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate static struct fop_subopt { 1117c478bd9Sstevel@tonic-gate char *str; 1127c478bd9Sstevel@tonic-gate int flag; 1137c478bd9Sstevel@tonic-gate } fop_subopt_list[] = { 1147c478bd9Sstevel@tonic-gate { UFSMNT_ONERROR_PANIC_STR, UFSMNT_ONERROR_PANIC }, 1157c478bd9Sstevel@tonic-gate { UFSMNT_ONERROR_LOCK_STR, UFSMNT_ONERROR_LOCK }, 1167c478bd9Sstevel@tonic-gate { UFSMNT_ONERROR_UMOUNT_STR, UFSMNT_ONERROR_UMOUNT }, 1177c478bd9Sstevel@tonic-gate { NULL, UFSMNT_ONERROR_DEFAULT } 1187c478bd9Sstevel@tonic-gate }; 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate /* 1227c478bd9Sstevel@tonic-gate * Check if the specified filesystem is already mounted. 1237c478bd9Sstevel@tonic-gate */ 1247c478bd9Sstevel@tonic-gate static boolean_t 1257c478bd9Sstevel@tonic-gate in_mnttab(char *mountp) 1267c478bd9Sstevel@tonic-gate { 1277c478bd9Sstevel@tonic-gate FILE *file; 1287c478bd9Sstevel@tonic-gate int found = B_FALSE; 1297c478bd9Sstevel@tonic-gate struct mnttab mntent; 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate if ((file = fopen(MNTTAB, "r")) == NULL) 1327c478bd9Sstevel@tonic-gate return (B_FALSE); 1337c478bd9Sstevel@tonic-gate while (getmntent(file, &mntent) == 0) { 1347c478bd9Sstevel@tonic-gate if (mntent.mnt_mountp != NULL && 1357c478bd9Sstevel@tonic-gate strcmp(mntent.mnt_mountp, mountp) == 0 && 1367c478bd9Sstevel@tonic-gate mntent.mnt_fstype != NULL && 1377c478bd9Sstevel@tonic-gate strcmp(mntent.mnt_fstype, MNTTYPE_UFS) == 0) { 1387c478bd9Sstevel@tonic-gate found = B_TRUE; 1397c478bd9Sstevel@tonic-gate break; 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate (void) fclose(file); 1437c478bd9Sstevel@tonic-gate return (found); 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate /* 1477c478bd9Sstevel@tonic-gate * Find opt in mntopt 1487c478bd9Sstevel@tonic-gate */ 1497c478bd9Sstevel@tonic-gate static char * 1507c478bd9Sstevel@tonic-gate findopt(char *mntopt, char *opt) 1517c478bd9Sstevel@tonic-gate { 1527c478bd9Sstevel@tonic-gate int nc, optlen = strlen(opt); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate while (*mntopt) { 1557c478bd9Sstevel@tonic-gate nc = strcspn(mntopt, ", ="); 1567c478bd9Sstevel@tonic-gate if (strncmp(mntopt, opt, nc) == 0) 1577c478bd9Sstevel@tonic-gate if (optlen == nc) 1587c478bd9Sstevel@tonic-gate return (mntopt); 1597c478bd9Sstevel@tonic-gate mntopt += nc; 1607c478bd9Sstevel@tonic-gate mntopt += strspn(mntopt, ", ="); 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate return (NULL); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate 165d1a180b0Smaheshvs int 1667c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 1677c478bd9Sstevel@tonic-gate { 1687c478bd9Sstevel@tonic-gate struct mnttab mnt; 1697c478bd9Sstevel@tonic-gate int c; 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1727c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 1737c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 1747c478bd9Sstevel@tonic-gate #endif 1757c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate myname = strrchr(argv[0], '/'); 1787c478bd9Sstevel@tonic-gate if (myname) 1797c478bd9Sstevel@tonic-gate myname++; 1807c478bd9Sstevel@tonic-gate else 1817c478bd9Sstevel@tonic-gate myname = argv[0]; 1827c478bd9Sstevel@tonic-gate (void) snprintf(typename, sizeof (typename), "%s %s", fstype, myname); 1837c478bd9Sstevel@tonic-gate argv[0] = typename; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate opts[0] = '\0'; 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate /* 1887c478bd9Sstevel@tonic-gate * Set options 1897c478bd9Sstevel@tonic-gate */ 1907c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "gmo:pqrVO")) != EOF) { 1917c478bd9Sstevel@tonic-gate switch (c) { 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate case 'g': 1947c478bd9Sstevel@tonic-gate gflg++; 1957c478bd9Sstevel@tonic-gate break; 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate case 'o': 1987c478bd9Sstevel@tonic-gate if (strlcpy(opts, optarg, sizeof (opts)) >= 1997c478bd9Sstevel@tonic-gate sizeof (opts)) { 2007c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("option string " 2017c478bd9Sstevel@tonic-gate "argument too long\n")); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate break; 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate case 'O': 2067c478bd9Sstevel@tonic-gate Oflg++; 2077c478bd9Sstevel@tonic-gate break; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate case 'r': 2107c478bd9Sstevel@tonic-gate ro++; 2117c478bd9Sstevel@tonic-gate break; 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate case 'm': 2147c478bd9Sstevel@tonic-gate mflg++; 2157c478bd9Sstevel@tonic-gate break; 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate case 'q': 2187c478bd9Sstevel@tonic-gate qflg++; 2197c478bd9Sstevel@tonic-gate break; 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate default: 2227c478bd9Sstevel@tonic-gate usage(); 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate if ((argc - optind) != 2) 2277c478bd9Sstevel@tonic-gate usage(); 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate mnt.mnt_special = argv[optind]; 2307c478bd9Sstevel@tonic-gate mnt.mnt_mountp = argv[optind+1]; 2317c478bd9Sstevel@tonic-gate mnt.mnt_fstype = fstype; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate /* 2347c478bd9Sstevel@tonic-gate * Process options. The resulting options string overwrites the 2357c478bd9Sstevel@tonic-gate * original. 2367c478bd9Sstevel@tonic-gate * 2377c478bd9Sstevel@tonic-gate * XXX: This code doesn't do a good job of resolving options that are 2387c478bd9Sstevel@tonic-gate * specified multiple times or that are given in conflicting 2397c478bd9Sstevel@tonic-gate * forms (e.g., both "largefiles" and "nolargefiles"). It also 2407c478bd9Sstevel@tonic-gate * doesn't produce well defined behavior for options that may 2417c478bd9Sstevel@tonic-gate * also be specified as flags (e.g, "-r" and "ro"/"rw") when both 2427c478bd9Sstevel@tonic-gate * are present. 2437c478bd9Sstevel@tonic-gate * 2447c478bd9Sstevel@tonic-gate * The proper way to deal with such conflicts is to start with 2457c478bd9Sstevel@tonic-gate * the default value (i.e., the one if no flag or option is 2467c478bd9Sstevel@tonic-gate * specified), override it with the last mentioned option pair 2477c478bd9Sstevel@tonic-gate * in the -o option string, and finally, override that with 2487c478bd9Sstevel@tonic-gate * the flag value. This allows "mount -r" command to mount a 2497c478bd9Sstevel@tonic-gate * file system read only that is listed rw in /etc/vfstab. 2507c478bd9Sstevel@tonic-gate */ 2517c478bd9Sstevel@tonic-gate mnt.mnt_mntopts = opts; 2527c478bd9Sstevel@tonic-gate if (findopt(mnt.mnt_mntopts, "m")) 2537c478bd9Sstevel@tonic-gate mflg++; 2547c478bd9Sstevel@tonic-gate if ((gflg || findopt(mnt.mnt_mntopts, MNTOPT_GLOBAL)) && 2557c478bd9Sstevel@tonic-gate findopt(mnt.mnt_mntopts, MNTOPT_NBMAND)) { 2567c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("NBMAND option not supported on" 2577c478bd9Sstevel@tonic-gate " global filesystem\n")); 2587c478bd9Sstevel@tonic-gate exit(32); 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate replace_opts(opts, ro, MNTOPT_RO, MNTOPT_RW); 2627c478bd9Sstevel@tonic-gate replace_opts(opts, largefiles, MNTOPT_NOLARGEFILES, MNTOPT_LARGEFILES); 2637c478bd9Sstevel@tonic-gate gflg = replace_opts_dflt(opts, gflg, MNTOPT_GLOBAL, MNTOPT_NOGLOBAL); 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate if (findopt(mnt.mnt_mntopts, MNTOPT_RQ)) { 2667c478bd9Sstevel@tonic-gate rmopt(&mnt, MNTOPT_RQ); 2677c478bd9Sstevel@tonic-gate replace_opts(opts, 1, MNTOPT_QUOTA, MNTOPT_NOQUOTA); 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate mountfs(&mnt); 271d1a180b0Smaheshvs return (0); 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate static void 2757c478bd9Sstevel@tonic-gate reportlogerror(int ret, char *mp, char *special, char *cmd, fiolog_t *flp) 2767c478bd9Sstevel@tonic-gate { 2777c478bd9Sstevel@tonic-gate /* No error */ 2787c478bd9Sstevel@tonic-gate if ((ret != -1) && (flp->error == FIOLOG_ENONE)) 2797c478bd9Sstevel@tonic-gate return; 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate /* logging was not enabled/disabled */ 2827c478bd9Sstevel@tonic-gate if (ret == -1 || flp->error != FIOLOG_ENONE) 2837c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Could not %s logging" 2847c478bd9Sstevel@tonic-gate " for %s on %s.\n"), cmd, mp, special); 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate /* ioctl returned error */ 2877c478bd9Sstevel@tonic-gate if (ret == -1) 2887c478bd9Sstevel@tonic-gate return; 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate /* Some more info */ 2917c478bd9Sstevel@tonic-gate switch (flp->error) { 2927c478bd9Sstevel@tonic-gate case FIOLOG_ENONE : 2937c478bd9Sstevel@tonic-gate if (flp->nbytes_requested && 2947c478bd9Sstevel@tonic-gate (flp->nbytes_requested != flp->nbytes_actual)) { 295*87c584d2Sbatschul (void) fprintf(stderr, gettext("The log has been" 296*87c584d2Sbatschul " resized from %d bytes to %d bytes.\n"), 2977c478bd9Sstevel@tonic-gate flp->nbytes_requested, 2987c478bd9Sstevel@tonic-gate flp->nbytes_actual); 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate return; 3017c478bd9Sstevel@tonic-gate case FIOLOG_ETRANS : 3027c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Solaris Volume Manager logging" 3037c478bd9Sstevel@tonic-gate " is already enabled.\n")); 3047c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Please see the" 3057c478bd9Sstevel@tonic-gate " commands metadetach(1M)" 3067c478bd9Sstevel@tonic-gate " or metaclear(1M).\n")); 3077c478bd9Sstevel@tonic-gate break; 3087c478bd9Sstevel@tonic-gate case FIOLOG_EROFS : 3097c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("File system is mounted read " 3107c478bd9Sstevel@tonic-gate "only.\n")); 3117c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Please see the remount " 3127c478bd9Sstevel@tonic-gate "option described in mount_ufs(1M).\n")); 3137c478bd9Sstevel@tonic-gate break; 3147c478bd9Sstevel@tonic-gate case FIOLOG_EULOCK : 3157c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("File system is locked.\n")); 3167c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Please see the -u option " 3177c478bd9Sstevel@tonic-gate "described in lockfs(1M).\n")); 3187c478bd9Sstevel@tonic-gate break; 3197c478bd9Sstevel@tonic-gate case FIOLOG_EWLOCK : 3207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("The file system could not be" 3217c478bd9Sstevel@tonic-gate " write locked.\n")); 3227c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Please see the -w option " 3237c478bd9Sstevel@tonic-gate "described in lockfs(1M).\n")); 3247c478bd9Sstevel@tonic-gate break; 3257c478bd9Sstevel@tonic-gate case FIOLOG_ECLEAN : 3267c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("The file system may not be" 3277c478bd9Sstevel@tonic-gate " stable.\n")); 3287c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Please see the -n option" 3297c478bd9Sstevel@tonic-gate " for fsck(1M).\n")); 3307c478bd9Sstevel@tonic-gate break; 3317c478bd9Sstevel@tonic-gate case FIOLOG_ENOULOCK : 3327c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("The file system could not be" 3337c478bd9Sstevel@tonic-gate " unlocked.\n")); 3347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Please see the -u option " 3357c478bd9Sstevel@tonic-gate "described in lockfs(1M).\n")); 3367c478bd9Sstevel@tonic-gate break; 3377c478bd9Sstevel@tonic-gate default : 3387c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Unknown internal error" 3397c478bd9Sstevel@tonic-gate " %d.\n"), flp->error); 3407c478bd9Sstevel@tonic-gate break; 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate static int 3457c478bd9Sstevel@tonic-gate checkislog(char *mp) 3467c478bd9Sstevel@tonic-gate { 3477c478bd9Sstevel@tonic-gate int fd; 3487c478bd9Sstevel@tonic-gate uint32_t islog; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate fd = open(mp, O_RDONLY); 3517c478bd9Sstevel@tonic-gate islog = 0; 3527c478bd9Sstevel@tonic-gate (void) ioctl(fd, _FIOISLOG, &islog); 3537c478bd9Sstevel@tonic-gate (void) close(fd); 3547c478bd9Sstevel@tonic-gate return ((int)islog); 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate static void 3587c478bd9Sstevel@tonic-gate enable_logging(char *mp, char *special) 3597c478bd9Sstevel@tonic-gate { 3607c478bd9Sstevel@tonic-gate int fd, ret, islog; 3617c478bd9Sstevel@tonic-gate fiolog_t fl; 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate fd = open(mp, O_RDONLY); 3647c478bd9Sstevel@tonic-gate if (fd == -1) { 3657c478bd9Sstevel@tonic-gate perror(mp); 3667c478bd9Sstevel@tonic-gate return; 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate fl.nbytes_requested = 0; 3697c478bd9Sstevel@tonic-gate fl.nbytes_actual = 0; 3707c478bd9Sstevel@tonic-gate fl.error = FIOLOG_ENONE; 3717c478bd9Sstevel@tonic-gate ret = ioctl(fd, _FIOLOGENABLE, &fl); 3727c478bd9Sstevel@tonic-gate if (ret == -1) 3737c478bd9Sstevel@tonic-gate perror(mp); 3747c478bd9Sstevel@tonic-gate (void) close(fd); 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate /* is logging enabled? */ 3777c478bd9Sstevel@tonic-gate islog = checkislog(mp); 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate /* report errors, if any */ 3807c478bd9Sstevel@tonic-gate if (ret == -1 || !islog) 3817c478bd9Sstevel@tonic-gate reportlogerror(ret, mp, special, "enable", &fl); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate static void 3857c478bd9Sstevel@tonic-gate disable_logging(char *mp, char *special) 3867c478bd9Sstevel@tonic-gate { 3877c478bd9Sstevel@tonic-gate int fd, ret, islog; 3887c478bd9Sstevel@tonic-gate fiolog_t fl; 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate fd = open(mp, O_RDONLY); 3917c478bd9Sstevel@tonic-gate if (fd == -1) { 3927c478bd9Sstevel@tonic-gate perror(mp); 3937c478bd9Sstevel@tonic-gate return; 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate fl.error = FIOLOG_ENONE; 3967c478bd9Sstevel@tonic-gate ret = ioctl(fd, _FIOLOGDISABLE, &fl); 3977c478bd9Sstevel@tonic-gate if (ret == -1) 3987c478bd9Sstevel@tonic-gate perror(mp); 3997c478bd9Sstevel@tonic-gate (void) close(fd); 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate /* is logging enabled? */ 4027c478bd9Sstevel@tonic-gate islog = checkislog(mp); 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate /* report errors, if any */ 4057c478bd9Sstevel@tonic-gate if (ret == -1 || islog) 4067c478bd9Sstevel@tonic-gate reportlogerror(ret, mp, special, "disable", &fl); 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate /* 4117c478bd9Sstevel@tonic-gate * attempt to mount file system, return errno or 0 4127c478bd9Sstevel@tonic-gate */ 4137c478bd9Sstevel@tonic-gate void 4147c478bd9Sstevel@tonic-gate mountfs(struct mnttab *mnt) 4157c478bd9Sstevel@tonic-gate { 4167c478bd9Sstevel@tonic-gate char opt[MAX_MNTOPT_STR]; 4177c478bd9Sstevel@tonic-gate char opt2[MAX_MNTOPT_STR]; 4187c478bd9Sstevel@tonic-gate char *opts = opt; 4197c478bd9Sstevel@tonic-gate int flags = MS_OPTIONSTR; 4207c478bd9Sstevel@tonic-gate struct ufs_args args; 4217c478bd9Sstevel@tonic-gate int need_separator = 0; 4227c478bd9Sstevel@tonic-gate int mount_attempts = 5; 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate (void) bzero((char *)&args, sizeof (args)); 4257c478bd9Sstevel@tonic-gate (void) strcpy(opts, mnt->mnt_mntopts); 4267c478bd9Sstevel@tonic-gate opt2[0] = '\0'; 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate flags |= Oflg ? MS_OVERLAY : 0; 4297c478bd9Sstevel@tonic-gate flags |= eatmntopt(mnt, MNTOPT_RO) ? MS_RDONLY : 0; 4307c478bd9Sstevel@tonic-gate flags |= eatmntopt(mnt, MNTOPT_REMOUNT) ? MS_REMOUNT : 0; 4317c478bd9Sstevel@tonic-gate flags |= eatmntopt(mnt, MNTOPT_GLOBAL) ? MS_GLOBAL : 0; 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_NOINTR)) 4347c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_NOINTR; 4357c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_INTR)) 4367c478bd9Sstevel@tonic-gate args.flags &= ~UFSMNT_NOINTR; 4377c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_SYNCDIR)) 4387c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_SYNCDIR; 4397c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_FORCEDIRECTIO)) { 4407c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_FORCEDIRECTIO; 4417c478bd9Sstevel@tonic-gate args.flags &= ~UFSMNT_NOFORCEDIRECTIO; 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_NOFORCEDIRECTIO)) { 4447c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_NOFORCEDIRECTIO; 4457c478bd9Sstevel@tonic-gate args.flags &= ~UFSMNT_FORCEDIRECTIO; 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_NOSETSEC)) 4487c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_NOSETSEC; 4497c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_LARGEFILES)) 4507c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_LARGEFILES; 4517c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_NOLARGEFILES)) 4527c478bd9Sstevel@tonic-gate args.flags &= ~UFSMNT_LARGEFILES; 4537c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_LOGGING; /* default is logging */ 4547c478bd9Sstevel@tonic-gate (void) eatmntopt(mnt, MNTOPT_LOGGING); 4557c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_NOLOGGING)) 4567c478bd9Sstevel@tonic-gate args.flags &= ~UFSMNT_LOGGING; 4577c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_NOATIME)) 4587c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_NOATIME; 4597c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_DFRATIME)) 4607c478bd9Sstevel@tonic-gate args.flags &= ~UFSMNT_NODFRATIME; 4617c478bd9Sstevel@tonic-gate if (eatmntopt(mnt, MNTOPT_NODFRATIME)) 4627c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_NODFRATIME; 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate while (*opts != '\0') { 4657c478bd9Sstevel@tonic-gate char *argval; 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate switch (getsubopt(&opts, fop_subopts, &argval)) { 4687c478bd9Sstevel@tonic-gate case ONERROR: 4697c478bd9Sstevel@tonic-gate if (argval) { 4707c478bd9Sstevel@tonic-gate struct fop_subopt *s; 4717c478bd9Sstevel@tonic-gate int found = 0; 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate for (s = fop_subopt_list; 4747c478bd9Sstevel@tonic-gate s->str && !found; 4757c478bd9Sstevel@tonic-gate s++) { 4767c478bd9Sstevel@tonic-gate if (strcmp(argval, s->str) == 0) { 4777c478bd9Sstevel@tonic-gate args.flags |= s->flag; 4787c478bd9Sstevel@tonic-gate found = 1; 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate } 4817c478bd9Sstevel@tonic-gate if (!found) { 4827c478bd9Sstevel@tonic-gate usage(); 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate if (need_separator) 4867c478bd9Sstevel@tonic-gate (void) strcat(opt2, ","); 4877c478bd9Sstevel@tonic-gate (void) strcat(opt2, MNTOPT_ONERROR); 4887c478bd9Sstevel@tonic-gate (void) strcat(opt2, "="); 4897c478bd9Sstevel@tonic-gate (void) strcat(opt2, argval); 4907c478bd9Sstevel@tonic-gate need_separator = 1; 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate } else { 4937c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_ONERROR_DEFAULT; 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate break; 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate case NOMATCH: 4987c478bd9Sstevel@tonic-gate default: 4997c478bd9Sstevel@tonic-gate if (argval) { 5007c478bd9Sstevel@tonic-gate if (need_separator) 5017c478bd9Sstevel@tonic-gate (void) strcat(opt2, ","); 5027c478bd9Sstevel@tonic-gate (void) strcat(opt2, argval); 5037c478bd9Sstevel@tonic-gate need_separator = 1; 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate break; 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate } 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate if (*opt2 != '\0') 5117c478bd9Sstevel@tonic-gate (void) strcpy(opt, opt2); 5127c478bd9Sstevel@tonic-gate opts = opt; 5137c478bd9Sstevel@tonic-gate if ((args.flags & UFSMNT_ONERROR_FLGMASK) == 0) 5147c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_ONERROR_DEFAULT; 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate (void) signal(SIGHUP, SIG_IGN); 5177c478bd9Sstevel@tonic-gate (void) signal(SIGQUIT, SIG_IGN); 5187c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_IGN); 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate errno = 0; 5217c478bd9Sstevel@tonic-gate flags |= MS_DATA | MS_OPTIONSTR; 5227c478bd9Sstevel@tonic-gate if (mflg) 5237c478bd9Sstevel@tonic-gate flags |= MS_NOMNTTAB; 5247c478bd9Sstevel@tonic-gate if (flags & MS_REMOUNT) { 5257c478bd9Sstevel@tonic-gate replace_opts(mnt->mnt_mntopts, 1, MNTOPT_RW, MNTOPT_RO); 5267c478bd9Sstevel@tonic-gate } 5277c478bd9Sstevel@tonic-gate fixopts(mnt, opts); 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate /* 5307c478bd9Sstevel@tonic-gate * For global filesystems we want to pass in logging option 5317c478bd9Sstevel@tonic-gate * so that it shows up in the mnttab of all nodes. We add 5327c478bd9Sstevel@tonic-gate * logging option if its not specified. 5337c478bd9Sstevel@tonic-gate */ 5347c478bd9Sstevel@tonic-gate if (gflg || findopt(mnt->mnt_mntopts, MNTOPT_GLOBAL)) { 535*87c584d2Sbatschul if (!(flags & MS_RDONLY)) { 5367c478bd9Sstevel@tonic-gate if (mnt->mnt_mntopts != '\0') 5377c478bd9Sstevel@tonic-gate (void) strcat(mnt->mnt_mntopts, ","); 5387c478bd9Sstevel@tonic-gate (void) strcat(mnt->mnt_mntopts, MNTOPT_LOGGING); 5397c478bd9Sstevel@tonic-gate args.flags |= UFSMNT_LOGGING; 540d87feeb8Ssjelinek } else { 541d87feeb8Ssjelinek /* 542d87feeb8Ssjelinek * Turn off logging for read only global mounts. 543d87feeb8Ssjelinek * It was set to logging as default above. 544d87feeb8Ssjelinek */ 545d87feeb8Ssjelinek if (mnt->mnt_mntopts != '\0') 546d87feeb8Ssjelinek (void) strcat(mnt->mnt_mntopts, ","); 547d87feeb8Ssjelinek (void) strcat(mnt->mnt_mntopts, MNTOPT_NOLOGGING); 548d87feeb8Ssjelinek args.flags &= ~UFSMNT_LOGGING; 549d87feeb8Ssjelinek } 5507c478bd9Sstevel@tonic-gate } 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate again: if (mount(mnt->mnt_special, mnt->mnt_mountp, flags, fstype, 5537c478bd9Sstevel@tonic-gate &args, sizeof (args), mnt->mnt_mntopts, MAX_MNTOPT_STR) != 0) { 5547c478bd9Sstevel@tonic-gate if (errno == EBUSY && !(flags & MS_OVERLAY)) { 5557c478bd9Sstevel@tonic-gate /* 5567c478bd9Sstevel@tonic-gate * Because of bug 6176743, any attempt to mount any 5577c478bd9Sstevel@tonic-gate * filesystem could fail for reasons described in that 5587c478bd9Sstevel@tonic-gate * bug. We're trying to detect that situation here by 5597c478bd9Sstevel@tonic-gate * checking that the filesystem we're mounting is not 5607c478bd9Sstevel@tonic-gate * in /etc/mnttab yet. When that bug is fixed, this 5617c478bd9Sstevel@tonic-gate * code can be removed. 5627c478bd9Sstevel@tonic-gate */ 5637c478bd9Sstevel@tonic-gate if (!in_mnttab(mnt->mnt_mountp) && 5647c478bd9Sstevel@tonic-gate mount_attempts-- > 0) { 5657c478bd9Sstevel@tonic-gate (void) poll(NULL, 0, 50); 5667c478bd9Sstevel@tonic-gate goto again; 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate } 5697c478bd9Sstevel@tonic-gate rpterr(mnt->mnt_special, mnt->mnt_mountp); 5707c478bd9Sstevel@tonic-gate exit(32); 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate if (!(flags & MS_RDONLY)) { 5747c478bd9Sstevel@tonic-gate if (args.flags & UFSMNT_LOGGING) 5757c478bd9Sstevel@tonic-gate enable_logging(mnt->mnt_mountp, mnt->mnt_special); 5767c478bd9Sstevel@tonic-gate else 5777c478bd9Sstevel@tonic-gate disable_logging(mnt->mnt_mountp, mnt->mnt_special); 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate if (!qflg) { 5817c478bd9Sstevel@tonic-gate cmp_requested_to_actual_options(opts, mnt->mnt_mntopts, 5827c478bd9Sstevel@tonic-gate mnt->mnt_special, mnt->mnt_mountp); 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate if (checkislog(mnt->mnt_mountp)) { 5867c478bd9Sstevel@tonic-gate /* update mnttab file if necessary */ 5877c478bd9Sstevel@tonic-gate if (!mflg) { 5887c478bd9Sstevel@tonic-gate struct stat64 statb; 5897c478bd9Sstevel@tonic-gate struct mnttagdesc mtdesc; 5907c478bd9Sstevel@tonic-gate int fd; 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate if (stat64(mnt->mnt_mountp, &statb) != 0) 5937c478bd9Sstevel@tonic-gate exit(32); 5947c478bd9Sstevel@tonic-gate /* do tag ioctl */ 5957c478bd9Sstevel@tonic-gate mtdesc.mtd_major = major(statb.st_dev); 5967c478bd9Sstevel@tonic-gate mtdesc.mtd_minor = minor(statb.st_dev); 5977c478bd9Sstevel@tonic-gate mtdesc.mtd_mntpt = mnt->mnt_mountp; 5987c478bd9Sstevel@tonic-gate mtdesc.mtd_tag = MNTOPT_LOGGING; 5997c478bd9Sstevel@tonic-gate if ((fd = open(MNTTAB, O_RDONLY, 0)) < 0) 6007c478bd9Sstevel@tonic-gate exit(32); 6017c478bd9Sstevel@tonic-gate if (ioctl(fd, MNTIOC_SETTAG, &mtdesc) != 0) { 6027c478bd9Sstevel@tonic-gate (void) close(fd); 6037c478bd9Sstevel@tonic-gate exit(32); 6047c478bd9Sstevel@tonic-gate } 6057c478bd9Sstevel@tonic-gate (void) close(fd); 6067c478bd9Sstevel@tonic-gate } 6077c478bd9Sstevel@tonic-gate } 6087c478bd9Sstevel@tonic-gate exit(0); 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate /* 6127c478bd9Sstevel@tonic-gate * same as findopt but remove the option from the option string and return 6137c478bd9Sstevel@tonic-gate * true or false 6147c478bd9Sstevel@tonic-gate */ 6157c478bd9Sstevel@tonic-gate static int 6167c478bd9Sstevel@tonic-gate eatmntopt(struct mnttab *mnt, char *opt) 6177c478bd9Sstevel@tonic-gate { 6187c478bd9Sstevel@tonic-gate int has; 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate has = (findopt(mnt->mnt_mntopts, opt) != NULL); 6217c478bd9Sstevel@tonic-gate rmopt(mnt, opt); 6227c478bd9Sstevel@tonic-gate return (has); 6237c478bd9Sstevel@tonic-gate } 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate /* 6267c478bd9Sstevel@tonic-gate * remove an option string from the option list 6277c478bd9Sstevel@tonic-gate */ 6287c478bd9Sstevel@tonic-gate static void 6297c478bd9Sstevel@tonic-gate rmopt(struct mnttab *mnt, char *opt) 6307c478bd9Sstevel@tonic-gate { 6317c478bd9Sstevel@tonic-gate char *str; 6327c478bd9Sstevel@tonic-gate char *optstart; 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate while (optstart = findopt(mnt->mnt_mntopts, opt)) { 6357c478bd9Sstevel@tonic-gate for (str = optstart; 6367c478bd9Sstevel@tonic-gate *str != ',' && *str != '\0' && *str != ' '; 6377c478bd9Sstevel@tonic-gate str++) 6387c478bd9Sstevel@tonic-gate /* NULL */; 6397c478bd9Sstevel@tonic-gate if (*str == ',') { 6407c478bd9Sstevel@tonic-gate str++; 6417c478bd9Sstevel@tonic-gate } else if (optstart != mnt->mnt_mntopts) { 6427c478bd9Sstevel@tonic-gate optstart--; 6437c478bd9Sstevel@tonic-gate } 6447c478bd9Sstevel@tonic-gate while (*optstart++ = *str++) 6457c478bd9Sstevel@tonic-gate ; 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate } 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate /* 6507c478bd9Sstevel@tonic-gate * mnt->mnt_ops has un-eaten opts, opts is the original opts list. 6517c478bd9Sstevel@tonic-gate * Set mnt->mnt_opts to the original, the kernel will then remove 6527c478bd9Sstevel@tonic-gate * the ones it cannot deal with. 6537c478bd9Sstevel@tonic-gate * Set "opts" to the the original options for later comparison in 6547c478bd9Sstevel@tonic-gate * cmp_....(). But strip the options which aren't returned by 6557c478bd9Sstevel@tonic-gate * the kernel: "noglobal", "global" and "quota". 6567c478bd9Sstevel@tonic-gate * And strip the options which aren't set through mount: "logging", 6577c478bd9Sstevel@tonic-gate * "nologging" from those passed to mount(2). 6587c478bd9Sstevel@tonic-gate */ 6597c478bd9Sstevel@tonic-gate static void 6607c478bd9Sstevel@tonic-gate fixopts(struct mnttab *mnt, char *opts) 6617c478bd9Sstevel@tonic-gate { 6627c478bd9Sstevel@tonic-gate struct mnttab omnt; 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate omnt.mnt_mntopts = opts; 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate /* 6677c478bd9Sstevel@tonic-gate * Options not passed to the kernel and possibly not returned; 6687c478bd9Sstevel@tonic-gate * these are dealt with using ioctl; and the ioctl may fail. 6697c478bd9Sstevel@tonic-gate */ 6707c478bd9Sstevel@tonic-gate rmopt(&omnt, MNTOPT_LOGGING); 6717c478bd9Sstevel@tonic-gate rmopt(&omnt, MNTOPT_NOLOGGING); 6727c478bd9Sstevel@tonic-gate 6737c478bd9Sstevel@tonic-gate /* 6747c478bd9Sstevel@tonic-gate * Set the options for ``/etc/mnttab'' to be the original 6757c478bd9Sstevel@tonic-gate * options from main(); except for the option "f" and "remount". 6767c478bd9Sstevel@tonic-gate */ 6777c478bd9Sstevel@tonic-gate (void) strlcpy(mnt->mnt_mntopts, opts, MAX_MNTOPT_STR); 6787c478bd9Sstevel@tonic-gate rmopt(mnt, "f"); 6797c478bd9Sstevel@tonic-gate rmopt(mnt, MNTOPT_REMOUNT); 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate rmopt(&omnt, MNTOPT_GLOBAL); 6827c478bd9Sstevel@tonic-gate rmopt(&omnt, MNTOPT_NOGLOBAL); 6837c478bd9Sstevel@tonic-gate rmopt(&omnt, MNTOPT_QUOTA); 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate static void 6877c478bd9Sstevel@tonic-gate usage(void) 6887c478bd9Sstevel@tonic-gate { 6897c478bd9Sstevel@tonic-gate (void) fprintf(stdout, gettext( 6907c478bd9Sstevel@tonic-gate "ufs usage:\n" 6917c478bd9Sstevel@tonic-gate "mount [-F ufs] [generic options] [-o suboptions] {special | mount_point}\n")); 6927c478bd9Sstevel@tonic-gate (void) fprintf(stdout, gettext( 6937c478bd9Sstevel@tonic-gate "\tsuboptions are: \n" 6947c478bd9Sstevel@tonic-gate "\t ro,rw,nosuid,remount,f,m,\n" 6957c478bd9Sstevel@tonic-gate "\t global,noglobal,\n" 6967c478bd9Sstevel@tonic-gate "\t largefiles,nolargefiles,\n" 6977c478bd9Sstevel@tonic-gate "\t forcedirectio,noforcedirectio\n" 6987c478bd9Sstevel@tonic-gate "\t logging,nologging,\n" 6997c478bd9Sstevel@tonic-gate "\t nbmand,nonbmand,\n" 7007c478bd9Sstevel@tonic-gate "\t onerror[={panic | lock | umount}]\n")); 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate exit(32); 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate /* 7067c478bd9Sstevel@tonic-gate * Returns the next option in the option string. 7077c478bd9Sstevel@tonic-gate */ 7087c478bd9Sstevel@tonic-gate static char * 7097c478bd9Sstevel@tonic-gate getnextopt(char **p) 7107c478bd9Sstevel@tonic-gate { 7117c478bd9Sstevel@tonic-gate char *cp = *p; 7127c478bd9Sstevel@tonic-gate char *retstr; 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate while (*cp && isspace(*cp)) 7157c478bd9Sstevel@tonic-gate cp++; 7167c478bd9Sstevel@tonic-gate retstr = cp; 7177c478bd9Sstevel@tonic-gate while (*cp && *cp != ',') 7187c478bd9Sstevel@tonic-gate cp++; 7197c478bd9Sstevel@tonic-gate /* strip empty options */ 7207c478bd9Sstevel@tonic-gate while (*cp == ',') { 7217c478bd9Sstevel@tonic-gate *cp = '\0'; 7227c478bd9Sstevel@tonic-gate cp++; 7237c478bd9Sstevel@tonic-gate } 7247c478bd9Sstevel@tonic-gate *p = cp; 7257c478bd9Sstevel@tonic-gate return (retstr); 7267c478bd9Sstevel@tonic-gate } 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate /* 7297c478bd9Sstevel@tonic-gate * "trueopt" and "falseopt" are two settings of a Boolean option. 7307c478bd9Sstevel@tonic-gate * If "flag" is true, forcibly set the option to the "true" setting; otherwise, 7317c478bd9Sstevel@tonic-gate * if the option isn't present, set it to the false setting. 7327c478bd9Sstevel@tonic-gate */ 7337c478bd9Sstevel@tonic-gate static void 7347c478bd9Sstevel@tonic-gate replace_opts(char *options, int flag, char *trueopt, char *falseopt) 7357c478bd9Sstevel@tonic-gate { 7367c478bd9Sstevel@tonic-gate char *f; 7377c478bd9Sstevel@tonic-gate char *tmpoptsp; 7387c478bd9Sstevel@tonic-gate int found; 7397c478bd9Sstevel@tonic-gate char tmptopts[MNTMAXSTR]; 7407c478bd9Sstevel@tonic-gate 7417c478bd9Sstevel@tonic-gate (void) strcpy(tmptopts, options); 7427c478bd9Sstevel@tonic-gate tmpoptsp = tmptopts; 7437c478bd9Sstevel@tonic-gate (void) strcpy(options, ""); 7447c478bd9Sstevel@tonic-gate 7457c478bd9Sstevel@tonic-gate found = 0; 7467c478bd9Sstevel@tonic-gate for (f = getnextopt(&tmpoptsp); *f; f = getnextopt(&tmpoptsp)) { 7477c478bd9Sstevel@tonic-gate if (options[0] != '\0') 7487c478bd9Sstevel@tonic-gate (void) strcat(options, ","); 7497c478bd9Sstevel@tonic-gate if (strcmp(f, trueopt) == 0) { 7507c478bd9Sstevel@tonic-gate (void) strcat(options, f); 7517c478bd9Sstevel@tonic-gate found++; 7527c478bd9Sstevel@tonic-gate } else if (strcmp(f, falseopt) == 0) { 7537c478bd9Sstevel@tonic-gate if (flag) 7547c478bd9Sstevel@tonic-gate (void) strcat(options, trueopt); 7557c478bd9Sstevel@tonic-gate else 7567c478bd9Sstevel@tonic-gate (void) strcat(options, f); 7577c478bd9Sstevel@tonic-gate found++; 7587c478bd9Sstevel@tonic-gate } else 7597c478bd9Sstevel@tonic-gate (void) strcat(options, f); 7607c478bd9Sstevel@tonic-gate } 7617c478bd9Sstevel@tonic-gate if (!found) { 7627c478bd9Sstevel@tonic-gate if (options[0] != '\0') 7637c478bd9Sstevel@tonic-gate (void) strcat(options, ","); 7647c478bd9Sstevel@tonic-gate (void) strcat(options, flag ? trueopt : falseopt); 7657c478bd9Sstevel@tonic-gate } 7667c478bd9Sstevel@tonic-gate } 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate /* 7697c478bd9Sstevel@tonic-gate * "trueopt" and "falseopt" are two settings of a Boolean option and "dflt" is 7707c478bd9Sstevel@tonic-gate * a default value for the option. Rewrite the contents of options to include 7717c478bd9Sstevel@tonic-gate * only the last mentioned occurrence of trueopt and falseopt. If neither is 7727c478bd9Sstevel@tonic-gate * mentioned, append one or the other to options, according to the value of 7737c478bd9Sstevel@tonic-gate * dflt. Return the resulting value of the option in boolean form. 7747c478bd9Sstevel@tonic-gate * 7757c478bd9Sstevel@tonic-gate * Note that the routine is implemented to have the resulting occurrence of 7767c478bd9Sstevel@tonic-gate * trueopt or falseopt appear at the end of the resulting option string. 7777c478bd9Sstevel@tonic-gate * 7787c478bd9Sstevel@tonic-gate * N.B. This routine should take the place of replace_opts, but there are 7797c478bd9Sstevel@tonic-gate * probably some compatibility issues to resolve before doing so. It 7807c478bd9Sstevel@tonic-gate * should certainly be used to handle new options that don't have 7817c478bd9Sstevel@tonic-gate * compatibility issues. 7827c478bd9Sstevel@tonic-gate */ 7837c478bd9Sstevel@tonic-gate static int 7847c478bd9Sstevel@tonic-gate replace_opts_dflt( 7857c478bd9Sstevel@tonic-gate char *options, 7867c478bd9Sstevel@tonic-gate int dflt, 7877c478bd9Sstevel@tonic-gate const char *trueopt, 7887c478bd9Sstevel@tonic-gate const char *falseopt) 7897c478bd9Sstevel@tonic-gate { 7907c478bd9Sstevel@tonic-gate char *f; 7917c478bd9Sstevel@tonic-gate char *tmpoptsp; 7927c478bd9Sstevel@tonic-gate int last; 7937c478bd9Sstevel@tonic-gate char tmptopts[MNTMAXSTR]; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate /* 7967c478bd9Sstevel@tonic-gate * Transfer the contents of options to tmptopts, in anticipation of 7977c478bd9Sstevel@tonic-gate * copying a subset of the contents back to options. 7987c478bd9Sstevel@tonic-gate */ 7997c478bd9Sstevel@tonic-gate (void) strcpy(tmptopts, options); 8007c478bd9Sstevel@tonic-gate tmpoptsp = tmptopts; 8017c478bd9Sstevel@tonic-gate (void) strcpy(options, ""); 8027c478bd9Sstevel@tonic-gate 8037c478bd9Sstevel@tonic-gate /* 8047c478bd9Sstevel@tonic-gate * Loop over each option value, copying non-matching values back into 8057c478bd9Sstevel@tonic-gate * options and updating the last seen occurrence of trueopt or 8067c478bd9Sstevel@tonic-gate * falseopt. 8077c478bd9Sstevel@tonic-gate */ 8087c478bd9Sstevel@tonic-gate last = dflt; 8097c478bd9Sstevel@tonic-gate for (f = getnextopt(&tmpoptsp); *f; f = getnextopt(&tmpoptsp)) { 8107c478bd9Sstevel@tonic-gate /* Check for both forms of the option of interest. */ 8117c478bd9Sstevel@tonic-gate if (strcmp(f, trueopt) == 0) { 8127c478bd9Sstevel@tonic-gate last = 1; 8137c478bd9Sstevel@tonic-gate } else if (strcmp(f, falseopt) == 0) { 8147c478bd9Sstevel@tonic-gate last = 0; 8157c478bd9Sstevel@tonic-gate } else { 8167c478bd9Sstevel@tonic-gate /* Not what we're looking for; transcribe. */ 8177c478bd9Sstevel@tonic-gate if (options[0] != '\0') 8187c478bd9Sstevel@tonic-gate (void) strcat(options, ","); 8197c478bd9Sstevel@tonic-gate (void) strcat(options, f); 8207c478bd9Sstevel@tonic-gate } 8217c478bd9Sstevel@tonic-gate } 8227c478bd9Sstevel@tonic-gate 8237c478bd9Sstevel@tonic-gate /* 8247c478bd9Sstevel@tonic-gate * Transcribe the correct form of the option of interest, using the 8257c478bd9Sstevel@tonic-gate * default value if it wasn't overwritten above. 8267c478bd9Sstevel@tonic-gate */ 8277c478bd9Sstevel@tonic-gate if (options[0] != '\0') 8287c478bd9Sstevel@tonic-gate (void) strcat(options, ","); 8297c478bd9Sstevel@tonic-gate (void) strcat(options, last ? trueopt : falseopt); 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate return (last); 8327c478bd9Sstevel@tonic-gate } 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate static void 8357c478bd9Sstevel@tonic-gate rpterr(char *bs, char *mp) 8367c478bd9Sstevel@tonic-gate { 8377c478bd9Sstevel@tonic-gate switch (errno) { 8387c478bd9Sstevel@tonic-gate case EPERM: 8397c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: Insufficient privileges\n"), 8407c478bd9Sstevel@tonic-gate myname); 8417c478bd9Sstevel@tonic-gate break; 8427c478bd9Sstevel@tonic-gate case ENXIO: 8437c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: %s no such device\n"), 8447c478bd9Sstevel@tonic-gate myname, bs); 8457c478bd9Sstevel@tonic-gate break; 8467c478bd9Sstevel@tonic-gate case ENOTDIR: 8477c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8487c478bd9Sstevel@tonic-gate gettext( 8497c478bd9Sstevel@tonic-gate "%s: %s not a directory\n\tor a component of %s is not a directory\n"), 8507c478bd9Sstevel@tonic-gate myname, mp, bs); 8517c478bd9Sstevel@tonic-gate break; 8527c478bd9Sstevel@tonic-gate case ENOENT: 8537c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 8547c478bd9Sstevel@tonic-gate "%s: %s or %s, no such file or directory\n"), 8557c478bd9Sstevel@tonic-gate myname, bs, mp); 8567c478bd9Sstevel@tonic-gate break; 8577c478bd9Sstevel@tonic-gate case EINVAL: 8587c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: %s is not this fstype\n"), 8597c478bd9Sstevel@tonic-gate myname, bs); 8607c478bd9Sstevel@tonic-gate break; 8617c478bd9Sstevel@tonic-gate case EBUSY: 8627c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8637c478bd9Sstevel@tonic-gate gettext("%s: %s is already mounted or %s is busy\n"), 8647c478bd9Sstevel@tonic-gate myname, bs, mp); 8657c478bd9Sstevel@tonic-gate break; 8667c478bd9Sstevel@tonic-gate case ENOTBLK: 8677c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 8687c478bd9Sstevel@tonic-gate "%s: %s not a block device\n"), myname, bs); 8697c478bd9Sstevel@tonic-gate break; 8707c478bd9Sstevel@tonic-gate case EROFS: 8717c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: %s write-protected\n"), 8727c478bd9Sstevel@tonic-gate myname, bs); 8737c478bd9Sstevel@tonic-gate break; 8747c478bd9Sstevel@tonic-gate case ENOSPC: 8757c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 8767c478bd9Sstevel@tonic-gate "%s: The state of %s is not okay\n" 8777c478bd9Sstevel@tonic-gate "\tand it was attempted to be mounted read/write\n"), 8787c478bd9Sstevel@tonic-gate myname, bs); 8797c478bd9Sstevel@tonic-gate (void) printf(gettext( 8807c478bd9Sstevel@tonic-gate "mount: Please run fsck and try again\n")); 8817c478bd9Sstevel@tonic-gate break; 8827c478bd9Sstevel@tonic-gate case EFBIG: 8837c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 8847c478bd9Sstevel@tonic-gate "%s: Large files may be present on %s,\n" 8857c478bd9Sstevel@tonic-gate "\tand it was attempted to be mounted nolargefiles\n"), 8867c478bd9Sstevel@tonic-gate myname, bs); 8877c478bd9Sstevel@tonic-gate break; 8887c478bd9Sstevel@tonic-gate default: 8897c478bd9Sstevel@tonic-gate perror(myname); 8907c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: Cannot mount %s\n"), 8917c478bd9Sstevel@tonic-gate myname, bs); 8927c478bd9Sstevel@tonic-gate } 8937c478bd9Sstevel@tonic-gate } 894