📄 mount.c
字号:
} if (u && is_in_proc(lowtype)) error ("mount: probably you meant %s", lowtype); else if (!strncmp(lowtype, "iso", 3) && is_in_proc("iso9660")) error ("mount: maybe you meant iso9660 ?"); free(lowtype); } else error ("mount: %s has wrong device number or fs type %s not supported", spec, type); break; case ENOTBLK: if (stat (spec, &statbuf)) /* strange ... */ error ("mount: %s is not a block device, and stat fails?", spec); else if (S_ISBLK(statbuf.st_mode)) error ("mount: the kernel does not recognize %s as a block device\n" " (maybe `insmod driver'?)", spec); else if (S_ISREG(statbuf.st_mode)) error ("mount: %s is not a block device (maybe try `-o loop'?)", spec); else error ("mount: %s is not a block device", spec); break; case ENXIO: error ("mount: %s is not a valid block device", spec); break; case EACCES: /* pre-linux 1.1.38, 1.1.41 and later */ case EROFS: /* linux 1.1.38 and later */ if (added_ro) { error ("mount: block device %s is not permitted on its filesystem", spec); break; } else { added_ro = 1; if (loop) { opts = opts0; type = type0; } if (opts) { opts = realloc(xstrdup(opts), strlen(opts)+4); strcat(opts, ",ro"); } else opts = "ro"; if (type && !strcmp(type, "guess")) type = 0; error ("mount: %s%s is write-protected, mounting read-only", loop ? "" : "block device ", spec0); return try_mount_one (spec0, node0, type, opts, freq, pass, bg); } break; default: error ("mount: %s", strerror (mnt_err)); break; } return EX_FAIL;}/* * set_proc_name() * Update the argument vector, so that this process may be easily * identified in a "ps" listing. */static voidset_proc_name (char *spec){#ifdef DO_PS_FIDDLING int i, l; /* * Move the environment so we can reuse the memory. * (Code borrowed from sendmail.) * WARNING: ugly assumptions on memory layout here; if this ever causes * problems, #undef DO_PS_FIDDLING */ for (i = 0; envp0[i] != NULL; i++) continue; environ = (char **) xmalloc(sizeof(char *) * (i + 1)); for (i = 0; envp0[i] != NULL; i++) environ[i] = xstrdup(envp0[i]); environ[i] = NULL; if (i > 0) l = envp0[i-1] + strlen(envp0[i-1]) - argv0[0]; else l = argv0[argc0-1] + strlen(argv0[argc0-1]) - argv0[0]; if (l > sizeof(PROC_NAME)) { strcpy(argv0[0], PROC_NAME); strncpy(argv0[0] + sizeof(PROC_NAME) - 1, spec, l - sizeof(PROC_NAME) - 1); argv0[1] = NULL; }#endif}intmount_one (char *spec, char *node, char *type, char *opts, char *cmdlineopts, int freq, int pass){ int status; int status2; /* Merge the fstab and command line options. */ if (opts == NULL) opts = cmdlineopts; else if (cmdlineopts != NULL) opts = xstrconcat3(opts, ",", cmdlineopts); if (type == NULL) { if (strchr (spec, ':') != NULL) { type = "nfs"; if (mount_verbose) printf("mount: no type was given - " "I'll assume nfs because of the colon\n"); } } /* * Try to mount the file system. When the exit status is EX_BG, * we will retry in the background. Otherwise, we're done. */ status = try_mount_one (spec, node, type, opts, freq, pass, 0); if (status != EX_BG) return status; /* * Retry in the background. */ printf ("mount: backgrounding \"%s\"\n", spec); fflush( stdout ); /* prevent duplicate output */ if (fork() > 0) return 0; /* parent returns "success" */ spec = xstrdup(spec); /* arguments will be destroyed */ node = xstrdup(node); /* by set_proc_name() */ type = xstrdup(type); opts = xstrdup(opts); set_proc_name (spec); /* make a nice "ps" listing */ status2 = try_mount_one (spec, node, type, opts, freq, pass, 1); if (mount_verbose && status2) printf ("mount: giving up \"%s\"\n", spec); exit (0); /* child stops here */}/* Check if an fsname/dir pair was already in the old mtab. */static intmounted (char *spec, char *node) { struct mntentchn *mc; spec = canonicalize (spec); node = canonicalize (node); for (mc = mtab_head()->nxt; mc; mc = mc->nxt) if (streq (spec, mc->mnt_fsname) && streq (node, mc->mnt_dir)) return 1; return 0;}/* Mount all filesystems of the specified types except swap and root. *//* With the --fork option: fork and let different incarnations of mount handle different filesystems. However, try to avoid several simultaneous mounts on the same physical disk, since that is very slow. */#define DISKMAJOR(m) (((int) m) & ~0xf)static intmount_all (string_list types, char *options) { struct mntentchn *mc, *mtmp; int status = 0; struct stat statbuf; struct child { pid_t pid; char *group; struct mntentchn *mec; struct mntentchn *meclast; struct child *nxt; } childhead, *childtail, *cp; char major[22]; char *g, *colon; /* build a chain of what we have to do, or maybe several chains, one for each major or NFS host */ childhead.nxt = 0; childtail = &childhead; for (mc = fstab_head()->nxt; mc; mc = mc->nxt) { if (matching_type (mc->mnt_type, types) && !streq (mc->mnt_dir, "/") && !streq (mc->mnt_dir, "root")) { if (mounted (mc->mnt_fsname, mc->mnt_dir)) { if (mount_verbose) printf("mount: %s already mounted on %s\n", mc->mnt_fsname, mc->mnt_dir); } else { mtmp = (struct mntentchn *) xmalloc(sizeof(*mtmp)); *mtmp = *mc; mtmp->nxt = 0; g = NULL; if (optfork) { if (stat(mc->mnt_fsname, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) { sprintf(major, "#%x", DISKMAJOR(statbuf.st_rdev)); g = major; }#if HAVE_NFS if (strcmp(mc->mnt_type, "nfs") == 0) { g = xstrdup(mc->mnt_fsname); colon = strchr(g, ':'); if (colon) *colon = '\0'; }#endif } if (g) { for (cp = childhead.nxt; cp; cp = cp->nxt) if (cp->group && strcmp(cp->group, g) == 0) { cp->meclast->nxt = mtmp; cp->meclast = mtmp; goto fnd; } } cp = (struct child *) xmalloc(sizeof *cp); cp->nxt = 0; cp->mec = cp->meclast = mtmp; cp->group = xstrdup(g); cp->pid = 0; childtail->nxt = cp; childtail = cp; fnd:; } } } /* now do everything */ for (cp = childhead.nxt; cp; cp = cp->nxt) { pid_t p = -1; if (optfork) { p = fork(); if (p == -1) error("mount: cannot fork: %s", strerror (errno)); else if (p != 0) cp->pid = p; } /* if child, or not forked, do the mounting */ if (p == 0 || p == -1) { for (mc = cp->mec; mc; mc = mc->nxt) status |= mount_one (mc->mnt_fsname, mc->mnt_dir, mc->mnt_type, mc->mnt_opts, options, 0, 0); if (mountcount) status |= EX_SOMEOK; if (p == 0) exit(status); } } /* wait for children, if any */ while ((cp = childhead.nxt) != NULL) { childhead.nxt = cp->nxt; if (cp->pid) { int ret; keep_waiting: if(waitpid(cp->pid, &ret, 0) == -1) { if (errno == EINTR) goto keep_waiting; perror("waitpid"); } else if (WIFEXITED(ret)) status |= WEXITSTATUS(ret); else status |= EX_SYSERR; } } if (mountcount) status |= EX_SOMEOK; return status;}extern char version[];static struct option longopts[] ={ { "all", 0, 0, 'a' }, { "fake", 0, 0, 'f' }, { "fork", 0, 0, 'F' }, { "help", 0, 0, 'h' }, { "no-mtab", 0, 0, 'n' }, { "read-only", 0, 0, 'r' }, { "ro", 0, 0, 'r' }, { "mount_verbose", 0, 0, 'v' }, { "version", 0, 0, 'V' }, { "read-write", 0, 0, 'w' }, { "rw", 0, 0, 'w' }, { "options", 1, 0, 'o' }, { "types", 1, 0, 't' }, { NULL, 0, 0, 0 }};const char *mount_usage_string = "\usage: mount [-hV]\n\ mount -a [-nfFrsvw] [-t vfstypes]\n\ mount [-nfrsvw] [-o options] special | node\n\ mount [-nfrsvw] [-t vfstype] [-o options] special node\n\";static voidusage (FILE *fp, int n){ fprintf (fp, "%s", mount_usage_string); unlock_mtab(); exit (n);}intmain_but_defunct (int argc, char *argv[]) { int c, result = 0; char *options = NULL, *spec; string_list types = NULL; struct mntentchn *mc; int fd; /* People report that a mount called from init without console writes error messages to /etc/mtab Let us try to avoid getting fd's 0,1,2 */ while((fd = open("/dev/null", O_RDWR)) == 0 || fd == 1 || fd == 2) ; if (fd > 2) close(fd);#ifdef DO_PS_FIDDLING argc0 = argc; argv0 = argv; envp0 = environ;#endif while ((c = getopt_long (argc, argv, "afFhno:rsvVwt:", longopts, NULL)) != EOF) switch (c) { case 'a': /* mount everything in fstab */ ++all; break; case 'f': /* fake (don't actually do mount(2) call) */ ++fake; break; case 'F': ++optfork; break; case 'h': /* help */ usage (stdout, 0); break; case 'n': /* mount without writing in /etc/mtab */ ++mount_nomtab; break; case 'o': /* specify mount options */ if (options) options = xstrconcat3(options, ",", optarg); else options = xstrdup(optarg); break; case 'r': /* mount readonly */ readonly = 1; readwrite = 0; break; case 's': /* allow sloppy mount options */ sloppy = 1; break; case 't': /* specify file system types */ types = parse_list (optarg); break; case 'v': /* be chatty - very chatty if repeated */ ++mount_verbose; break; case 'V': /* version */ printf ("mount: %s\n", version); exit (0); case 'w': /* mount read/write */ readwrite = 1; readonly = 0; break; case 0: break; case '?': default: usage (stderr, EX_USAGE); } argc -= optind; argv += optind; if (argc == 0 && !all) { if (options) usage (stderr, EX_USAGE); return print_all (types); } if (getuid () != geteuid ()) { mount_suid = 1; if (types || options || readwrite || mount_nomtab || all || fake || argc != 1) die (EX_USAGE, "mount: only root can do that"); } if (!mount_nomtab && mtab_does_not_exist()) { if (mount_verbose > 1) printf("mount: no %s found - creating it..\n", MOUNTED); create_mtab (); } switch (argc) { case 0: /* mount -a */ result = mount_all (types, options); if (result == 0 && mount_verbose) error("not mounted anything"); break; case 1: /* mount [-nfrvw] [-o options] special | node */ if (types != NULL) usage (stderr, EX_USAGE); /* Try to find the other pathname in fstab. */ spec = canonicalize (*argv); if ((mc = getmntfile (spec)) == NULL && (mc = getfsspec (spec)) == NULL && (mc = getfsfile (spec)) == NULL && /* Try noncanonical name in fstab perhaps /dev/cdrom or /dos is a symlink */ (mc = getfsspec (*argv)) == NULL && (mc = getfsfile (*argv)) == NULL) die (EX_USAGE, "mount: can't find %s in %s or %s", spec, MOUNTED, _PATH_FSTAB); result = mount_one (xstrdup (mc->mnt_fsname), xstrdup (mc->mnt_dir), xstrdup (mc->mnt_type), mc->mnt_opts, options, 0, 0); break; case 2: /* mount [-nfrvw] [-t vfstype] [-o options] special node */ if (types == NULL) result = mount_one (argv[0], argv[1], NULL, NULL, options, 0, 0); else if (cdr (types) == NULL) result = mount_one (argv[0], argv[1], car (types), NULL, options, 0, 0); else usage (stderr, EX_USAGE); break; default: usage (stderr, EX_USAGE); } if (result == EX_SOMEOK) result = 0; exit (result);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -