/** * mnt_context_mount: * @cxt: mount context * * High-level, mounts filesystem by mount(2) or fork()+exec(/sbin/mount.type). * * This is similar to: * * mnt_context_prepare_mount(cxt); * mnt_context_do_mount(cxt); * mnt_context_finalize_mount(cxt); * * See also mnt_context_disable_helpers(). * * Note that this function could be called only once. If you want to mount with * different setting than you have to call mnt_reset_context(). It's NOT enough * to call mnt_context_reset_status() if you want call this function more than * once, whole context has to be reseted. * * WARNING: non-zero return code does not mean that mount(2) syscall or * mount.type helper wasn't successfully called. * * Check mnt_context_get_status() after error! * * Returns: 0 on success; * >0 in case of mount(2) error (returns syscall errno), * <0 in case of other errors. */ int mnt_context_mount(struct libmnt_context *cxt) { int rc; assert(cxt); assert(cxt->fs); assert(cxt->helper_exec_status == 1); assert(cxt->syscall_status == 1); rc = mnt_context_prepare_mount(cxt); if (!rc) rc = mnt_context_prepare_update(cxt); if (!rc) rc = mnt_context_do_mount(cxt); /* TODO: if mtab update is expected then check if the * target is really mounted read-write to avoid 'ro' in * mtab and 'rw' in /proc/mounts. */ if (!rc) rc = mnt_context_update_tabs(cxt); return rc; }
static int mount_main(struct libmnt_context *cxt, int argc, char **argv) { int rc, c; struct libmnt_fs *fs; char *spec = NULL, *mount_point = NULL, *opts = NULL; static const struct option longopts[] = { { "fake", 0, 0, 'f' }, { "help", 0, 0, 'h' }, { "no-mtab", 0, 0, 'n' }, { "read-only", 0, 0, 'r' }, { "ro", 0, 0, 'r' }, { "verbose", 0, 0, 'v' }, { "version", 0, 0, 'V' }, { "read-write", 0, 0, 'w' }, { "rw", 0, 0, 'w' }, { "options", 1, 0, 'o' }, { "sloppy", 0, 0, 's' }, { NULL, 0, 0, 0 } }; mount_config_init(progname); mnt_context_init_helper(cxt, MNT_ACT_MOUNT, 0); while ((c = getopt_long(argc, argv, "fhnrVvwo:s", longopts, NULL)) != -1) { rc = mnt_context_helper_setopt(cxt, c, optarg); if (rc == 0) /* valid option */ continue; if (rc < 0) /* error (probably ENOMEM) */ goto err; /* rc==1 means unknow option */ switch (c) { case 'V': printf("%s: ("PACKAGE_STRING")\n", progname); return EX_SUCCESS; case 'h': default: mount_usage(); return EX_USAGE; } } if (optind < argc) spec = argv[optind++]; if (optind < argc) mount_point = argv[optind++]; if (!mount_point) { nfs_error(_("%s: no mount point provided"), progname); goto err; } if (!spec) { nfs_error(_("%s: no mount spec provided"), progname); goto err; } if (geteuid() != 0) { nfs_error(_("%s: not installed setuid - " "\"user\" NFS mounts not supported."), progname); goto err; } verbose = mnt_context_is_verbose(cxt); sloppy = mnt_context_is_sloppy(cxt); nomtab = mnt_context_is_nomtab(cxt); if (strcmp(progname, "mount.nfs4") == 0) mnt_context_set_fstype(cxt, "nfs4"); else mnt_context_set_fstype(cxt, "nfs"); /* default */ rc = mnt_context_set_source(cxt, spec); if (!rc) mnt_context_set_target(cxt, mount_point); if (rc) { nfs_error(_("%s: failed to set spec or mountpoint: %s"), progname, strerror(errno)); goto err; } mount_point = mnt_resolve_path(mount_point, mnt_context_get_cache(cxt)); if (chk_mountpoint(mount_point)) goto err; /* * Concatenate mount options from the configuration file */ fs = mnt_context_get_fs(cxt); if (fs) { opts = mnt_fs_strdup_options(fs); opts = mount_config_opts(spec, mount_point, opts); mnt_fs_set_options(fs, opts); } rc = mnt_context_prepare_mount(cxt); if (rc) { nfs_error(_("%s: failed to prepare mount: %s\n"), progname, strerror(-rc)); goto err; } rc = try_mount(cxt, FOREGROUND); if (rc == EX_BG) { printf(_("%s: backgrounding \"%s\"\n"), progname, mnt_context_get_source(cxt)); printf(_("%s: mount options: \"%s\"\n"), progname, opts); fflush(stdout); if (daemon(0, 0)) { nfs_error(_("%s: failed to start " "background process: %s\n"), progname, strerror(errno)); exit(EX_FAIL); } rc = try_mount(cxt, BACKGROUND); if (verbose && rc) printf(_("%s: giving up \"%s\"\n"), progname, mnt_context_get_source(cxt)); } mnt_context_set_syscall_status(cxt, rc == EX_SUCCESS ? 0 : -1); mnt_context_finalize_mount(cxt); /* mtab update */ return rc; err: return EX_FAIL; }