[BACK]Return to mount_puffs.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / mount_puffs

Annotation of src/sbin/mount_puffs/mount_puffs.c, Revision 1.5

1.5     ! pho         1: /*     $NetBSD: mount_puffs.c,v 1.4 2011/08/29 14:35:02 joerg Exp $    */
1.1       pooka       2:
                      3: /*
                      4:  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     16:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     18:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     19:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     20:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     21:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     23:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     25:  * SUCH DAMAGE.
                     26:  */
                     27:
                     28: /*
1.5     ! pho        29:  * This is to support -o getargs without having to replicate it in
        !            30:  * every file server. It also allows puffs filesystems to be mounted
        !            31:  * via "mount -a".
1.1       pooka      32:  */
                     33:
                     34: #include <sys/cdefs.h>
                     35: #ifndef lint
1.5     ! pho        36: __RCSID("$NetBSD: mount_puffs.c,v 1.4 2011/08/29 14:35:02 joerg Exp $");
1.1       pooka      37: #endif /* !lint */
                     38:
                     39: #include <sys/param.h>
                     40: #include <sys/mount.h>
                     41:
                     42: #include <fs/puffs/puffs_msgif.h>
                     43:
                     44: #include <err.h>
                     45: #include <stdio.h>
                     46: #include <stdlib.h>
1.5     ! pho        47: #include <string.h>
        !            48: #include <sys/cdefs.h>
1.1       pooka      49: #include <unistd.h>
1.5     ! pho        50: #include <util.h>
1.1       pooka      51:
1.5     ! pho        52: static int
1.1       pooka      53: usage(void)
                     54: {
                     55:
1.5     ! pho        56:        fprintf(stderr, "usage: %s [-o options] program[#source] mountpoint\n", getprogname());
        !            57:        return 1;
1.1       pooka      58: }
                     59:
1.5     ! pho        60: static int show_puffs_mount_args(const char *mountpoint)
1.1       pooka      61: {
                     62:        const char *vtypes[] = { VNODE_TYPES };
                     63:        struct puffs_kargs kargs;
                     64:
1.5     ! pho        65:        if (mount(MOUNT_PUFFS, mountpoint, MNT_GETARGS, &kargs, sizeof(kargs)) == -1)
        !            66:                err(1, "mount");
1.1       pooka      67:
1.3       pooka      68:        printf("version=%d, ", kargs.pa_vers);
1.1       pooka      69:        printf("flags=0x%x, ", kargs.pa_flags);
                     70:
                     71:        printf("root cookie=%p, ", kargs.pa_root_cookie);
                     72:        printf("root type=%s", vtypes[kargs.pa_root_vtype]);
                     73:
                     74:        if (kargs.pa_root_vtype != VDIR)
                     75:                printf(", root size=%llu",
                     76:                    (unsigned long long)kargs.pa_root_vsize);
                     77:        if (kargs.pa_root_vtype == VCHR || kargs.pa_root_vtype == VBLK)
                     78:                printf(", root rdev=0x%" PRIx64, (uint64_t)kargs.pa_root_rdev);
                     79:        printf("\n");
1.2       pooka      80:
                     81:        return 0;
1.1       pooka      82: }
1.5     ! pho        83:
        !            84: static int
        !            85: mount_puffs_filesystem(const char *program, const char *opts,
        !            86:                                        const char *source, const char *mountpoint)
        !            87: {
        !            88:        int argc = 0;
        !            89:        const char **argv;
        !            90:        int rv = 0;
        !            91:
        !            92:        /* Construct an argument vector:
        !            93:         * program [-o opts] [source] mountpoint */
        !            94:        argv = ecalloc(1 + 2 + 1 + 1, sizeof(*argv));
        !            95:        argv[argc++] = program;
        !            96:        if (opts != NULL) {
        !            97:                argv[argc++] = "-o";
        !            98:                argv[argc++] = opts;
        !            99:        }
        !           100:        if (source != NULL) {
        !           101:                argv[argc++] = source;
        !           102:        }
        !           103:        argv[argc++] = mountpoint;
        !           104:        argv[argc] = NULL;
        !           105:
        !           106:        /* We intentionally use execvp(3) here because the program can
        !           107:         * actually be a basename. */
        !           108:        if (execvp(program, __UNCONST(argv)) == -1) {
        !           109:                warn("Cannot execute %s", program);
        !           110:                rv = 1;
        !           111:        }
        !           112:
        !           113:        free(argv);
        !           114:        return rv;
        !           115: }
        !           116:
        !           117: static void add_opt(char **opts, const char *opt)
        !           118: {
        !           119:        const size_t orig_len = *opts == NULL ? 0 : strlen(*opts);
        !           120:
        !           121:        *opts = erealloc(*opts, orig_len + 1 + strlen(opt) + 1);
        !           122:
        !           123:        if (orig_len == 0) {
        !           124:                strcpy(*opts, opt);
        !           125:        }
        !           126:        else {
        !           127:                strcat(*opts, ",");
        !           128:                strcat(*opts, opt);
        !           129:        }
        !           130: }
        !           131:
        !           132: int
        !           133: main(int argc, char *argv[])
        !           134: {
        !           135:        int mntflags = 0;
        !           136:        int ch;
        !           137:        char *opts = NULL;
        !           138:        int rv = 0;
        !           139:
        !           140:        while ((ch = getopt(argc, argv, "o:")) != -1) {
        !           141:                switch (ch) {
        !           142:                case 'o':
        !           143:                        for (char *opt = optarg; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
        !           144:                                if (strcmp(opt, "getargs") == 0) {
        !           145:                                        mntflags |= MNT_GETARGS;
        !           146:                                        break; /* No need to parse it any further. */
        !           147:                                }
        !           148:                                else {
        !           149:                                        add_opt(&opts, opt);
        !           150:                                }
        !           151:                        }
        !           152:                        break;
        !           153:                default:
        !           154:                        rv = usage();
        !           155:                        goto free_opts;
        !           156:                }
        !           157:        }
        !           158:        argc -= optind;
        !           159:        argv += optind;
        !           160:
        !           161:        if (argc != 2) {
        !           162:                rv = usage();
        !           163:                goto free_opts;
        !           164:        }
        !           165:
        !           166:        if (mntflags & MNT_GETARGS) {
        !           167:                /* Special case for -o getargs: retrieve kernel arguments for
        !           168:                 * an already mounted filesystem. */
        !           169:                rv = show_puffs_mount_args(argv[1]);
        !           170:        }
        !           171:        else {
        !           172:                /* Split the program name and source. This is to allow
        !           173:                 * filesystems to be mounted via "mount -a" i.e. /etc/fstab */
        !           174:                char *source  = argv[0];
        !           175:                char *program = strsep(&source, "#");
        !           176:
        !           177:                rv = mount_puffs_filesystem(program, opts, source, argv[1]);
        !           178:        }
        !           179:
        !           180: free_opts:
        !           181:        free(opts);
        !           182:        return rv;
        !           183: }

CVSweb <webmaster@jp.NetBSD.org>