wip import mount_sysvbfs
This commit is contained in:
parent
5084102fbc
commit
cfbb0c09fc
|
|
@ -1222,6 +1222,7 @@
|
|||
./usr/sbin/pwd_mkdb minix-base
|
||||
./usr/sbin/rdate minix-base
|
||||
./usr/sbin/rump.traceroute minix-base rump
|
||||
./usr/sbin/rump_sysvbfs minix-base rump
|
||||
./usr/sbin/syslogd minix-base
|
||||
./usr/sbin/traceroute minix-base
|
||||
./usr/sbin/unlink minix-base
|
||||
|
|
|
|||
|
|
@ -2297,6 +2297,7 @@
|
|||
./usr/lib/libobjc.a minix-comp gcc=45
|
||||
./usr/lib/libobjc_pic.a minix-comp gcc=45
|
||||
./usr/lib/libp2k.a minix-comp rump
|
||||
./usr/lib/libp2k_pic.a minix-comp rump
|
||||
./usr/lib/libpci.a minix-comp
|
||||
./usr/lib/libpci_pic.a minix-comp
|
||||
./usr/lib/libprop.a minix-comp
|
||||
|
|
@ -2462,6 +2463,7 @@
|
|||
./usr/lib/libtimers.a minix-comp
|
||||
./usr/lib/libtimers_pic.a minix-comp
|
||||
./usr/lib/libukfs.a minix-comp rump
|
||||
./usr/lib/libukfs_pic.a minix-comp rump
|
||||
./usr/lib/libusb.a minix-comp
|
||||
./usr/lib/libusb_pic.a minix-comp
|
||||
./usr/lib/libutil.a minix-comp
|
||||
|
|
|
|||
|
|
@ -3444,6 +3444,7 @@
|
|||
./usr/man/man8/repartition.8 minix-man
|
||||
./usr/man/man8/rotate.8 minix-man
|
||||
./usr/man/man8/rshd.8 minix-man
|
||||
./usr/man/man8/rump_sysvbfs.8 minix-man rump
|
||||
./usr/man/man8/screendump.8 minix-man
|
||||
./usr/man/man8/serial-ip.8 minix-man obsolete
|
||||
./usr/man/man8/service.8 minix-man
|
||||
|
|
|
|||
46
sbin/mount/pathadj.c
Normal file
46
sbin/mount/pathadj.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/* $NetBSD: pathadj.c,v 1.2 2011/02/17 16:57:46 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 The NetBSD Foundation. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mountprog.h"
|
||||
|
||||
void
|
||||
pathadj(const char *input, char *adjusted)
|
||||
{
|
||||
|
||||
if (realpath(input, adjusted) == NULL)
|
||||
warn("Warning: realpath %s", input);
|
||||
if (strncmp(input, adjusted, MAXPATHLEN)) {
|
||||
warnx("\"%s\" is a non-resolved or relative path.", input);
|
||||
warnx("using \"%s\" instead.", adjusted);
|
||||
}
|
||||
}
|
||||
16
sbin/mount_sysvbfs/Makefile
Normal file
16
sbin/mount_sysvbfs/Makefile
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# $NetBSD: Makefile,v 1.2 2008/09/04 12:07:58 pooka Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= mount_sysvbfs
|
||||
SRCS= mount_sysvbfs.c fattr.c pathadj.c
|
||||
MAN= mount_sysvbfs.8
|
||||
|
||||
MOUNT= ${NETBSDSRCDIR}/sbin/mount
|
||||
CPPFLAGS+= -I${MOUNT}
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
DPADD+=${LIBUTIL}
|
||||
LDADD+=-lutil
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
80
sbin/mount_sysvbfs/mount_sysvbfs.8
Normal file
80
sbin/mount_sysvbfs/mount_sysvbfs.8
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
.\" $NetBSD: mount_sysvbfs.8,v 1.1 2005/12/29 14:53:45 tsutsui Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1989, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)mount.8 8.7 (Berkeley) 3/27/94
|
||||
.\"
|
||||
.Dd September 21, 2005
|
||||
.Dt MOUNT_SYSVBFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mount_sysvbfs
|
||||
.Nd mount a System V Boot File System
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl o Ar options
|
||||
.Ar special node
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
command attaches the System V Boot File System on the
|
||||
.Ar special
|
||||
device on to the file system tree at point
|
||||
.Ar node .
|
||||
Both
|
||||
.Ar special
|
||||
and
|
||||
.Ar node
|
||||
are converted to absolute paths before use.
|
||||
.Pp
|
||||
This command is normally executed by
|
||||
.Xr mount 8
|
||||
at boot time.
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl o
|
||||
Options are specified with a
|
||||
.Fl o
|
||||
flag followed by a comma separated string of options.
|
||||
See the
|
||||
.Xr mount 8
|
||||
man page for possible options and their meanings.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mount 2 ,
|
||||
.Xr unmount 2 ,
|
||||
.Xr fstab 5 ,
|
||||
.Xr mount 8
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command first appeared in
|
||||
.Nx 4.0 .
|
||||
.Sh BUGS
|
||||
The sysvbfs support is still experimental and there are few sanity checks,
|
||||
so it is possible for a corrupted file system to cause a crash.
|
||||
157
sbin/mount_sysvbfs/mount_sysvbfs.c
Normal file
157
sbin/mount_sysvbfs/mount_sysvbfs.c
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/* $NetBSD: mount_sysvbfs.c,v 1.8 2011/08/29 14:35:02 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1993, 1994\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: mount_sysvbfs.c,v 1.8 2011/08/29 14:35:02 joerg Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <mntopts.h>
|
||||
|
||||
#include "mountprog.h"
|
||||
#include "mount_sysvbfs.h"
|
||||
|
||||
static const struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
MOPT_UPDATE,
|
||||
MOPT_GETARGS,
|
||||
MOPT_NULL,
|
||||
};
|
||||
|
||||
__dead static void
|
||||
sysvbfs_usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "usage: %s [-o options] special node\n",
|
||||
getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifndef MOUNT_NOMAIN
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
||||
return mount_sysvbfs(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
mount_sysvbfs_parseargs(int argc, char **argv,
|
||||
struct sysvbfs_args *args, int *mntflags,
|
||||
char *canon_dev, char *canon_dir)
|
||||
{
|
||||
int ch;
|
||||
mntoptparse_t mp;
|
||||
|
||||
*mntflags = 0;
|
||||
optind = optreset = 1; /* Reset for parse of new argv. */
|
||||
while ((ch = getopt(argc, argv, "o:")) != -1)
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
mp = getmntopts(optarg, mopts, mntflags, 0);
|
||||
if (mp == NULL)
|
||||
err(1, "getmntopts");
|
||||
freemntopts(mp);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
sysvbfs_usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 2)
|
||||
sysvbfs_usage();
|
||||
|
||||
pathadj(argv[0], canon_dev);
|
||||
args->fspec = canon_dev;
|
||||
pathadj(argv[1], canon_dir);
|
||||
}
|
||||
|
||||
int
|
||||
mount_sysvbfs(int argc, char *argv[])
|
||||
{
|
||||
struct sysvbfs_args args;
|
||||
char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
const char *errcause;
|
||||
int mntflags;
|
||||
|
||||
mount_sysvbfs_parseargs(argc, argv, &args, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
|
||||
if (mount(MOUNT_SYSVBFS, canon_dir, mntflags, &args, sizeof args)==-1) {
|
||||
switch (errno) {
|
||||
case EMFILE:
|
||||
errcause = "mount table full";
|
||||
break;
|
||||
case EINVAL:
|
||||
if (mntflags & MNT_UPDATE)
|
||||
errcause =
|
||||
"specified device does not match mounted device";
|
||||
else
|
||||
errcause = "incorrect super block";
|
||||
break;
|
||||
default:
|
||||
errcause = strerror(errno);
|
||||
break;
|
||||
}
|
||||
errx(EXIT_FAILURE, "%s on %s: %s",
|
||||
canon_dev, canon_dir, errcause);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
#if defined(__minix)
|
||||
int __real_main(int argc, char *argv[]);
|
||||
|
||||
int
|
||||
__real_main(int argc, char *argv[])
|
||||
{
|
||||
return mount_sysvbfs(argc, argv);
|
||||
}
|
||||
#endif
|
||||
37
sbin/mount_sysvbfs/mount_sysvbfs.h
Normal file
37
sbin/mount_sysvbfs/mount_sysvbfs.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* $NetBSD: mount_sysvbfs.h,v 1.1 2008/09/04 12:07:58 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 The NetBSD Foundation. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SBIN_MOUNT_SYSVBFS_MOUNT_SYSVBFS_H_
|
||||
#define _SBIN_MOUNT_SYSVBFS_MOUNT_SYSVBFS_H_
|
||||
|
||||
#include <fs/sysvbfs/sysvbfs_args.h>
|
||||
|
||||
int mount_sysvbfs(int, char **);
|
||||
void mount_sysvbfs_parseargs(int, char **, struct sysvbfs_args *, int *,
|
||||
char *, char *);
|
||||
|
||||
#endif /* _SBIN_MOUNT_SYSVBFS_MOUNT_SYSVBFS_H_ */
|
||||
|
|
@ -44,7 +44,7 @@ SUBDIR+= rpc.yppasswdd ypbind yppoll ypserv ypset
|
|||
.endif
|
||||
|
||||
.if (${MKRUMP} != "no")
|
||||
#SUBDIR+= puffs
|
||||
SUBDIR+= puffs
|
||||
.endif
|
||||
|
||||
.if ${TOOLCHAIN_MISSING} != "no"
|
||||
|
|
|
|||
37
usr.sbin/puffs/Makefile
Normal file
37
usr.sbin/puffs/Makefile
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# $NetBSD: Makefile,v 1.16 2011/07/24 08:55:30 uch Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.if !defined(__MINIX)
|
||||
SUBDIR= mount_9p mount_psshfs mount_sysctlfs
|
||||
|
||||
SUBDIR+=rump_cd9660 rump_efs rump_ext2fs rump_ffs rump_hfs rump_lfs
|
||||
SUBDIR+=rump_msdos rump_nfs rump_ntfs rump_syspuffs rump_sysvbfs
|
||||
SUBDIR+=rump_tmpfs rump_udf rump_v7fs
|
||||
|
||||
.if ${MKCRYPTO} != "no"
|
||||
SUBDIR+=rump_smbfs
|
||||
.endif
|
||||
.else
|
||||
SUBDIR= rump_sysvbfs
|
||||
.endif
|
||||
|
||||
#
|
||||
# The following are not built by default
|
||||
#
|
||||
|
||||
# userspace fdesc server cannot grope the fd info from the kernel,
|
||||
# and is therefore not useful for the average user
|
||||
#SUBDIR+=rump_fdesc
|
||||
|
||||
# ditto for kernfs
|
||||
#SUBDIR+=rump_kernfs
|
||||
|
||||
# rump_mqmfs is just another ffs, useful mainly for debugging
|
||||
#SUBDIR+=rump_nqmfs
|
||||
|
||||
# rump_au-naturel presents lets you access '/' for a rump kernel.
|
||||
# mostly for debugging.
|
||||
#SUBDIR+=rump_au-naturel
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
58
usr.sbin/puffs/Makefile.inc
Normal file
58
usr.sbin/puffs/Makefile.inc
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# $NetBSD: Makefile.inc,v 1.14 2014/01/16 01:15:34 christos Exp $
|
||||
|
||||
WARNS?= 4
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
USE_FORT?= yes # network client
|
||||
|
||||
.if exists(${.CURDIR}/../../Makefile.inc)
|
||||
.include "${.CURDIR}/../../Makefile.inc"
|
||||
.endif
|
||||
|
||||
.ifdef ISRUMP
|
||||
.ifdef MOUNTNAME
|
||||
PROG= rump_${MOUNTNAME}
|
||||
MAN= rump_${MOUNTNAME}.8
|
||||
|
||||
MOUNTDIR= ${.CURDIR}/../../../sbin
|
||||
MOUNT= ${MOUNTDIR}/mount
|
||||
|
||||
CPPFLAGS+= -I${MOUNTDIR}/mount_${MOUNTNAME} -I${MOUNT} -DMOUNT_NOMAIN
|
||||
SRCS+= mount_${MOUNTNAME}.c rump_${MOUNTNAME}.c pathadj.c fattr.c
|
||||
|
||||
# on select archs use the kernel module directly, otherwise fallback
|
||||
# to the rump library
|
||||
.ifndef DONOTLINKLIBS
|
||||
.undef RUMPKMOD
|
||||
.ifdef RUMPKMOD
|
||||
OSRELEASE!= ${HOST_SH} ${NETBSDSRCDIR}/sys/conf/osrelease.sh
|
||||
KMODULEDIR= ${DESTDIR}/stand/${MACHINE}/${OSRELEASE}/modules/${MOUNTNAME}
|
||||
LDADD+= ${KMODULEDIR}/${MOUNTNAME}.kmod
|
||||
.else
|
||||
LDADD+= -lrumpfs_${MOUNTNAME}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.PATH: ${MOUNT} ${MOUNTDIR}/mount_${MOUNTNAME}
|
||||
.endif # MOUNTNAME
|
||||
|
||||
# disk components for disk-based file systems
|
||||
.if RUMP_DISKFS
|
||||
LDADD+= -lrumpdev_disk -lrumpdev
|
||||
.endif
|
||||
|
||||
LDADD+= -lp2k -lukfs -lrumpvfs -lrump -lrumpuser -lpuffs -lutil
|
||||
.if defined(__MINIX)
|
||||
LDADD+= -lmthread -lfsdriver -lsys
|
||||
.else
|
||||
LDADD+= -lpthread
|
||||
.endif # defined(__MINIX)
|
||||
|
||||
DPADD+= ${LIBP2K} ${LIBUKFS} ${LIBRUMPVFS} ${LIBRUMP} ${LIBRUMPUSER}
|
||||
.if defined(__MINIX)
|
||||
DPADD+= ${LIBPUFFS} ${LIBUTIL} ${LIBMTHREAD}
|
||||
.else
|
||||
DPADD+= ${LIBPUFFS} ${LIBUTIL} ${LIBPTHREAD}
|
||||
.endif # defined(__MINIX)
|
||||
.endif # ISRUMP
|
||||
232
usr.sbin/puffs/makerumpmanpages.sh
Normal file
232
usr.sbin/puffs/makerumpmanpages.sh
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: makerumpmanpages.sh,v 1.13 2011/07/24 08:55:30 uch Exp $
|
||||
#
|
||||
|
||||
IFS=' '
|
||||
COPYRIGHT='.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: $NetBSD: makerumpmanpages.sh,v 1.13 2011/07/24 08:55:30 uch Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"'
|
||||
|
||||
MANTMPL1='.Dd November 21, 2010
|
||||
.Dt RUMP_XXXFSXXX 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_xxxfsxxx
|
||||
.Nd mount a xxxfsxxx xxxfssrcxxx with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar xxximagexxx
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_xxxfsxxx 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount xxxfsxxx file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_xxxfsxxx 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.'
|
||||
|
||||
MANTMPL_BLK='.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar xxximagexxx
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar xxximagexxx
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_xxxfsxxx 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.'
|
||||
|
||||
MANTMPL_NET='.Pp
|
||||
Even though the
|
||||
.Nm
|
||||
file system client runs within a virtual rump kernel in userspace,
|
||||
it uses host network services
|
||||
.Pq by means of Dq rump sockin .
|
||||
This means that regardless of whether using
|
||||
.Nm
|
||||
or
|
||||
.Xr mount_xxxfsxxx 8 ,
|
||||
the same network configurations will be used.
|
||||
Currently,
|
||||
.Dq sockin
|
||||
supports IPv4.'
|
||||
|
||||
MANTMPL2='.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar xxxfsxxx
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_xxxfsxxx 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_xxxfsxxx 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx xxxfirstxxx .'
|
||||
|
||||
# vary manpages slightly based on the type of server in question
|
||||
disk="cd9660 efs ext2fs ffs hfs lfs msdos ntfs sysvbfs udf v7fs"
|
||||
net="nfs smbfs"
|
||||
fictional="fdesc kernfs tmpfs"
|
||||
special="au-naturel nqmfs syspuffs"
|
||||
|
||||
first5="cd9660 efs ext2fs ffs hfs lfs msdos nfs ntfs syspuffs sysvbfs tmpfs udf"
|
||||
|
||||
member ()
|
||||
{
|
||||
|
||||
what=$1
|
||||
shift
|
||||
|
||||
while [ $# -gt 0 ] ; do
|
||||
[ "$1" = "${what}" ] && return 0
|
||||
shift
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
sedsub='s/xxxfsxxx/$fs/g\;s/XXXFSXXX/$fsc/g\;s/xxximagexxx/$image/g\;'\
|
||||
's/xxxfirstxxx/$first/g\;s/xxxfssrcxxx/$fssrc/g\;'
|
||||
|
||||
# auto manual pages
|
||||
for x in rump_*
|
||||
do
|
||||
fs=${x#rump_}
|
||||
|
||||
# see if we are dealing with a new server
|
||||
if ! member $fs $disk $net $fictional $special ; then
|
||||
echo ERROR: $fs not found in any class!
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# special file systems have special manpages
|
||||
member $fs $special && continue
|
||||
|
||||
# figure out our type
|
||||
if member $fs $disk ; then
|
||||
mytype=disk
|
||||
image=image
|
||||
fssrc=image
|
||||
fi
|
||||
if member $fs $net ; then
|
||||
mytype=net
|
||||
image=share
|
||||
fssrc=share
|
||||
fi
|
||||
if member $fs $fictional ; then
|
||||
mytype=special
|
||||
image=$fs
|
||||
fssrc='fictional fs'
|
||||
fi
|
||||
|
||||
# which version did server first appear?
|
||||
if member $fs $first5 ; then
|
||||
first=5.0
|
||||
else
|
||||
first=6.0
|
||||
fi
|
||||
|
||||
fsc=`echo $fs | tr '[:lower:]' '[:upper:]'`
|
||||
eval sedstr="${sedsub}"
|
||||
|
||||
printf '.\\" $NetBSD: makerumpmanpages.sh,v 1.13 2011/07/24 08:55:30 uch Exp $\n.\\"\n' > rump_${fs}/rump_${fs}.8
|
||||
echo ${COPYRIGHT} | sed -e 's/\$//g' >> rump_${fs}/rump_${fs}.8
|
||||
|
||||
echo ${MANTMPL1} | sed -e "$sedstr" >> rump_${fs}/rump_${fs}.8
|
||||
[ ${mytype} = disk ] && \
|
||||
echo ${MANTMPL_BLK} | sed -e "$sedstr" >> rump_${fs}/rump_${fs}.8
|
||||
[ ${mytype} = net ] && \
|
||||
echo ${MANTMPL_NET} | sed -e "$sedstr" >> rump_${fs}/rump_${fs}.8
|
||||
echo ${MANTMPL2} | sed -e "$sedstr" >> rump_${fs}/rump_${fs}.8
|
||||
done
|
||||
10
usr.sbin/puffs/mount_9p/Makefile
Normal file
10
usr.sbin/puffs/mount_9p/Makefile
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# $NetBSD: Makefile,v 1.3 2009/04/22 15:23:06 lukem Exp $
|
||||
#
|
||||
|
||||
PROG= mount_9p
|
||||
SRCS= ninepuffs.c ninebuf.c nineproto.c fs.c node.c subr.c
|
||||
LDADD+= -lpuffs -lutil
|
||||
|
||||
MAN= mount_9p.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
236
usr.sbin/puffs/mount_9p/fs.c
Normal file
236
usr.sbin/puffs/mount_9p/fs.c
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/* $NetBSD: fs.c,v 1.9 2011/06/22 04:03:23 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: fs.c,v 1.9 2011/06/22 04:03:23 mrg Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <puffs.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ninepuffs.h"
|
||||
#include "nineproto.h"
|
||||
|
||||
#define DO_IO(fname, a1, a2, a3, a4, rv) \
|
||||
puffs_framebuf_seekset(a2, 0); \
|
||||
*(a4) = 0; \
|
||||
rv = fname(a1, a2, a3, a4); \
|
||||
if (rv) errx(1, "p9p_handshake io failed %d, %d", rv, *a4)
|
||||
|
||||
struct puffs_node *
|
||||
p9p_handshake(struct puffs_usermount *pu,
|
||||
const char *username, const char *path)
|
||||
{
|
||||
struct puffs9p *p9p = puffs_getspecific(pu);
|
||||
struct puffs_framebuf *pb;
|
||||
struct puffs_node *pn;
|
||||
struct vattr rootva;
|
||||
uint32_t maxreq;
|
||||
uint16_t dummy;
|
||||
p9ptag_t tagid, rtagid;
|
||||
p9pfid_t curfid;
|
||||
const char *p;
|
||||
uint8_t type;
|
||||
int rv, done, x = 1, ncomp;
|
||||
|
||||
/* send initial handshake */
|
||||
pb = p9pbuf_makeout();
|
||||
p9pbuf_put_1(pb, P9PROTO_T_VERSION);
|
||||
p9pbuf_put_2(pb, P9PROTO_NOTAG);
|
||||
p9pbuf_put_4(pb, p9p->maxreq);
|
||||
p9pbuf_put_str(pb, P9PROTO_VERSION);
|
||||
DO_IO(p9pbuf_write, pu, pb, p9p->servsock, &done, rv);
|
||||
|
||||
puffs_framebuf_recycle(pb);
|
||||
DO_IO(p9pbuf_read, pu, pb, p9p->servsock, &done, rv);
|
||||
|
||||
if ((type = p9pbuf_get_type(pb)) != P9PROTO_R_VERSION)
|
||||
errx(1, "server invalid response to Tversion: %d", type);
|
||||
if ((rtagid = p9pbuf_get_tag(pb)) != P9PROTO_NOTAG) {
|
||||
errx(1, "server invalid tag: %d vs. %d",
|
||||
P9PROTO_NOTAG, rtagid);
|
||||
return NULL;
|
||||
}
|
||||
if (p9pbuf_get_4(pb, &maxreq))
|
||||
errx(1, "server invalid response: no request length");
|
||||
if (maxreq < P9P_MINREQLEN)
|
||||
errx(1, "server request length below minimum accepted: "
|
||||
"%d vs. %d", P9P_MINREQLEN, maxreq);
|
||||
p9p->maxreq = maxreq;
|
||||
|
||||
/* tell the server we don't support authentication */
|
||||
p9pbuf_recycleout(pb);
|
||||
tagid = NEXTTAG(p9p);
|
||||
p9pbuf_put_1(pb, P9PROTO_T_AUTH);
|
||||
p9pbuf_put_2(pb, tagid);
|
||||
p9pbuf_put_4(pb, P9PROTO_NOFID);
|
||||
p9pbuf_put_str(pb, username);
|
||||
p9pbuf_put_str(pb, "");
|
||||
DO_IO(p9pbuf_write, pu, pb, p9p->servsock, &done, rv);
|
||||
|
||||
puffs_framebuf_recycle(pb);
|
||||
DO_IO(p9pbuf_read, pu, pb, p9p->servsock, &done, rv);
|
||||
|
||||
/* assume all Rerror is "no auth" */
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_ERROR)
|
||||
errx(1, "mount_9p supports only NO auth");
|
||||
if ((rtagid = p9pbuf_get_tag(pb)) != tagid)
|
||||
errx(1, "server invalid tag: %d vs. %d", tagid, rtagid);
|
||||
|
||||
/* build attach message */
|
||||
p9pbuf_recycleout(pb);
|
||||
tagid = NEXTTAG(p9p);
|
||||
p9pbuf_put_1(pb, P9PROTO_T_ATTACH);
|
||||
p9pbuf_put_2(pb, tagid);
|
||||
p9pbuf_put_4(pb, P9P_ROOTFID);
|
||||
p9pbuf_put_4(pb, P9PROTO_NOFID);
|
||||
p9pbuf_put_str(pb, username);
|
||||
p9pbuf_put_str(pb, "");
|
||||
DO_IO(p9pbuf_write, pu, pb, p9p->servsock, &done, rv);
|
||||
|
||||
puffs_framebuf_recycle(pb);
|
||||
DO_IO(p9pbuf_read, pu, pb, p9p->servsock, &done, rv);
|
||||
|
||||
if ((type = p9pbuf_get_type(pb)) != P9PROTO_R_ATTACH)
|
||||
errx(1, "Rattach not received, got %d", type);
|
||||
if ((rtagid = p9pbuf_get_tag(pb)) != tagid)
|
||||
errx(1, "server invalid tag: %d vs. %d", tagid, rtagid);
|
||||
|
||||
/* just walk away rootfid, you won't see me follow you back home */
|
||||
|
||||
#define EATSLASH(p) while (*(p) == '/') p++
|
||||
assert(*path == '/');
|
||||
p = path;
|
||||
EATSLASH(p);
|
||||
for (ncomp = 0; p && *p; ncomp++) {
|
||||
EATSLASH(p);
|
||||
if (!*p)
|
||||
break;
|
||||
p = strchr(p, '/');
|
||||
}
|
||||
|
||||
if (ncomp == 0) {
|
||||
curfid = P9P_ROOTFID;
|
||||
} else {
|
||||
uint16_t walked;
|
||||
|
||||
p9pbuf_recycleout(pb);
|
||||
tagid = NEXTTAG(p9p);
|
||||
curfid = NEXTFID(p9p);
|
||||
p9pbuf_put_1(pb, P9PROTO_T_WALK);
|
||||
p9pbuf_put_2(pb, tagid);
|
||||
p9pbuf_put_4(pb, P9P_ROOTFID);
|
||||
p9pbuf_put_4(pb, curfid);
|
||||
p9pbuf_put_2(pb, ncomp);
|
||||
|
||||
p = path;
|
||||
while (p && *p) {
|
||||
char *p2;
|
||||
|
||||
EATSLASH(p);
|
||||
if (!*p)
|
||||
break;
|
||||
if ((p2 = strchr(p, '/')) == NULL)
|
||||
p2 = strchr(p, '\0');
|
||||
p9pbuf_put_data(pb, p, p2-p);
|
||||
p = p2;
|
||||
}
|
||||
|
||||
DO_IO(p9pbuf_write, pu, pb, p9p->servsock, &done, rv);
|
||||
|
||||
puffs_framebuf_recycle(pb);
|
||||
DO_IO(p9pbuf_read, pu, pb, p9p->servsock, &done, rv);
|
||||
|
||||
if ((type = p9pbuf_get_type(pb)) != P9PROTO_R_WALK)
|
||||
errx(1, "Rwalk not received for rnode, got %d", type);
|
||||
if ((rtagid = p9pbuf_get_tag(pb)) != tagid)
|
||||
errx(1, "server invalid tag: %d vs. %d",
|
||||
tagid, rtagid);
|
||||
if (p9pbuf_get_2(pb, &walked) == -1)
|
||||
errx(1, "can't get number of walked qids");
|
||||
if (walked != ncomp)
|
||||
errx(1, "can't locate rootpath %s, only %d/%d "
|
||||
"components found", path, walked, ncomp);
|
||||
|
||||
/* curfid is alive, clunk P9P_ROOTFID */
|
||||
p9pbuf_recycleout(pb);
|
||||
tagid = NEXTTAG(p9p);
|
||||
p9pbuf_put_1(pb, P9PROTO_T_CLUNK);
|
||||
p9pbuf_put_2(pb, tagid);
|
||||
p9pbuf_put_4(pb, P9P_ROOTFID);
|
||||
|
||||
DO_IO(p9pbuf_write, pu, pb, p9p->servsock, &done, rv);
|
||||
puffs_framebuf_recycle(pb);
|
||||
DO_IO(p9pbuf_read, pu, pb, p9p->servsock, &done, rv);
|
||||
/* wedontcare */
|
||||
}
|
||||
|
||||
/* finally, stat the node */
|
||||
p9pbuf_recycleout(pb);
|
||||
tagid = NEXTTAG(p9p);
|
||||
p9pbuf_put_1(pb, P9PROTO_T_STAT);
|
||||
p9pbuf_put_2(pb, tagid);
|
||||
p9pbuf_put_4(pb, curfid);
|
||||
DO_IO(p9pbuf_write, pu, pb, p9p->servsock, &done, rv);
|
||||
|
||||
puffs_framebuf_recycle(pb);
|
||||
DO_IO(p9pbuf_read, pu, pb, p9p->servsock, &done, rv);
|
||||
|
||||
if ((type = p9pbuf_get_type(pb)) != P9PROTO_R_STAT)
|
||||
errx(1, "Rstat not received, got %d", type);
|
||||
if ((rtagid = p9pbuf_get_tag(pb)) != tagid)
|
||||
errx(1, "server invalid tag: %d vs. %d", tagid, rtagid);
|
||||
if (p9pbuf_get_2(pb, &dummy))
|
||||
errx(1, "couldn't get stat len parameter");
|
||||
if (proto_getstat(pb, &rootva, NULL, NULL))
|
||||
errx(1, "could not parse root attributes");
|
||||
puffs_framebuf_destroy(pb);
|
||||
|
||||
rootva.va_nlink = 0156; /* guess, will be fixed with first readdir */
|
||||
pn = newp9pnode_va(pu, &rootva, curfid);
|
||||
|
||||
if (ioctl(p9p->servsock, FIONBIO, &x) == -1)
|
||||
err(1, "cannot set socket in nonblocking mode");
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_fs_unmount(struct puffs_usermount *pu, int flags)
|
||||
{
|
||||
struct puffs9p *p9p = puffs_getspecific(pu);
|
||||
|
||||
close(p9p->servsock);
|
||||
return 0;
|
||||
}
|
||||
70
usr.sbin/puffs/mount_9p/mount_9p.8
Normal file
70
usr.sbin/puffs/mount_9p/mount_9p.8
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
.\" $NetBSD: mount_9p.8,v 1.4 2007/12/02 21:03:32 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2007 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd July 8, 2007
|
||||
.Dt MOUNT_9P 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mount_9p
|
||||
.Nd mount a file server using the 9P resource sharing protocol
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl s
|
||||
.Op Fl o Ar mntopts
|
||||
.Op Fl p Ar port
|
||||
.Ar [user@]host[:path]
|
||||
.Ar mount_point
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program is used to mount a file hierarchy served with the Plan 9
|
||||
file sharing protocol: 9P.
|
||||
After the file system is mounted, the files on the remote
|
||||
.Ar host
|
||||
will be accessed using the credentials of the user named
|
||||
.Ar user
|
||||
and whatever UID the user happens to have on the remote server.
|
||||
If
|
||||
.Ar path
|
||||
is supplied, it is used as the mount rootpath on the remote host.
|
||||
.Ar path
|
||||
must be an absolute path.
|
||||
.Sh SEE ALSO
|
||||
.Xr puffs 3 ,
|
||||
.Xr puffs 4 ,
|
||||
.Xr mount 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
.Sh CAVEATS
|
||||
Permissions are not handled well.
|
||||
.Pp
|
||||
Authentication support is missing.
|
||||
.Pp
|
||||
Error code handling is missing.
|
||||
.Pp
|
||||
Under construction.
|
||||
338
usr.sbin/puffs/mount_9p/ninebuf.c
Normal file
338
usr.sbin/puffs/mount_9p/ninebuf.c
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
/* $NetBSD: ninebuf.c,v 1.8 2012/11/04 22:38:19 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2007 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ninebuf.c,v 1.8 2012/11/04 22:38:19 christos Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ninepuffs.h"
|
||||
|
||||
#define CHECK(v) if (!(v)) abort()
|
||||
|
||||
uint8_t
|
||||
p9pbuf_get_type(struct puffs_framebuf *pb)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
puffs_framebuf_getdata_atoff(pb, 4, &val, 1);
|
||||
return val;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
p9pbuf_get_tag(struct puffs_framebuf *pb)
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
puffs_framebuf_getdata_atoff(pb, 5, &val, 2);
|
||||
return le16toh(val);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
p9pbuf_get_len(struct puffs_framebuf *pb)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
puffs_framebuf_getdata_atoff(pb, 0, &val, 4);
|
||||
return le32toh(val);
|
||||
}
|
||||
|
||||
#define CUROFF(pb) (puffs_framebuf_telloff(pb))
|
||||
int
|
||||
p9pbuf_read(struct puffs_usermount *pu, struct puffs_framebuf *pb,
|
||||
int fd, int *done)
|
||||
{
|
||||
void *win;
|
||||
ssize_t n;
|
||||
size_t howmuch, winlen;
|
||||
int lenstate;
|
||||
|
||||
the_next_level:
|
||||
if ((lenstate = (CUROFF(pb) < 4)))
|
||||
howmuch = 4 - CUROFF(pb);
|
||||
else
|
||||
howmuch = p9pbuf_get_len(pb) - CUROFF(pb);
|
||||
|
||||
if (puffs_framebuf_reserve_space(pb, howmuch) == -1)
|
||||
return errno;
|
||||
|
||||
while (howmuch) {
|
||||
winlen = howmuch;
|
||||
if (puffs_framebuf_getwindow(pb, CUROFF(pb), &win, &winlen)==-1)
|
||||
return errno;
|
||||
n = read(fd, win, winlen);
|
||||
switch (n) {
|
||||
case 0:
|
||||
return ECONNRESET;
|
||||
case -1:
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
return errno;
|
||||
default:
|
||||
howmuch -= n;
|
||||
puffs_framebuf_seekset(pb, CUROFF(pb) + n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lenstate) {
|
||||
puffs_framebuf_seekset(pb, 7);
|
||||
*done = 1;
|
||||
return 0;
|
||||
} else
|
||||
goto the_next_level;
|
||||
}
|
||||
|
||||
int
|
||||
p9pbuf_write(struct puffs_usermount *pu, struct puffs_framebuf *pb,
|
||||
int fd, int *done)
|
||||
{
|
||||
void *win;
|
||||
ssize_t n;
|
||||
size_t winlen, howmuch;
|
||||
|
||||
if (CUROFF(pb) == 0) {
|
||||
uint32_t len;
|
||||
|
||||
len = htole32(puffs_framebuf_tellsize(pb));
|
||||
puffs_framebuf_putdata_atoff(pb, 0, &len, 4);
|
||||
}
|
||||
|
||||
howmuch = puffs_framebuf_tellsize(pb) - CUROFF(pb);
|
||||
while (howmuch) {
|
||||
winlen = howmuch;
|
||||
if (puffs_framebuf_getwindow(pb, CUROFF(pb), &win, &winlen)==-1)
|
||||
return errno;
|
||||
n = send(fd, win, winlen, MSG_NOSIGNAL);
|
||||
switch (n) {
|
||||
case 0:
|
||||
return ECONNRESET;
|
||||
case -1:
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
return errno;
|
||||
default:
|
||||
howmuch -= n;
|
||||
puffs_framebuf_seekset(pb, CUROFF(pb) + n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*done = 1;
|
||||
return 0;
|
||||
}
|
||||
#undef CUROFF
|
||||
|
||||
int
|
||||
p9pbuf_cmp(struct puffs_usermount *pu,
|
||||
struct puffs_framebuf *c1, struct puffs_framebuf *c2, int *notresp)
|
||||
{
|
||||
|
||||
return p9pbuf_get_tag(c1) != p9pbuf_get_tag(c2);
|
||||
}
|
||||
|
||||
struct puffs_framebuf *
|
||||
p9pbuf_makeout()
|
||||
{
|
||||
struct puffs_framebuf *pb;
|
||||
|
||||
pb = puffs_framebuf_make();
|
||||
puffs_framebuf_seekset(pb, 4);
|
||||
return pb;
|
||||
}
|
||||
|
||||
void
|
||||
p9pbuf_recycleout(struct puffs_framebuf *pb)
|
||||
{
|
||||
|
||||
puffs_framebuf_recycle(pb);
|
||||
puffs_framebuf_seekset(pb, 4);
|
||||
}
|
||||
|
||||
void
|
||||
p9pbuf_put_1(struct puffs_framebuf *pb, uint8_t val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = puffs_framebuf_putdata(pb, &val, 1);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
void
|
||||
p9pbuf_put_2(struct puffs_framebuf *pb, uint16_t val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
HTOLE16(val);
|
||||
rv = puffs_framebuf_putdata(pb, &val, 2);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
void
|
||||
p9pbuf_put_4(struct puffs_framebuf *pb, uint32_t val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
HTOLE32(val);
|
||||
rv = puffs_framebuf_putdata(pb, &val, 4);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
void
|
||||
p9pbuf_put_8(struct puffs_framebuf *pb, uint64_t val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
HTOLE64(val);
|
||||
rv = puffs_framebuf_putdata(pb, &val, 8);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
void
|
||||
p9pbuf_put_data(struct puffs_framebuf *pb, const void *data, uint16_t dlen)
|
||||
{
|
||||
int rv;
|
||||
|
||||
p9pbuf_put_2(pb, dlen);
|
||||
rv = puffs_framebuf_putdata(pb, data, dlen);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
void
|
||||
p9pbuf_put_str(struct puffs_framebuf *pb, const char *str)
|
||||
{
|
||||
|
||||
p9pbuf_put_data(pb, str, strlen(str));
|
||||
}
|
||||
|
||||
void
|
||||
p9pbuf_write_data(struct puffs_framebuf *pb, uint8_t *data, uint32_t dlen)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = puffs_framebuf_putdata(pb, data, dlen);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
#define ERETURN(rv) return ((rv) == -1 ? errno : 0)
|
||||
|
||||
int
|
||||
p9pbuf_get_1(struct puffs_framebuf *pb, uint8_t *val)
|
||||
{
|
||||
|
||||
ERETURN(puffs_framebuf_getdata(pb, val, 1));
|
||||
}
|
||||
|
||||
int
|
||||
p9pbuf_get_2(struct puffs_framebuf *pb, uint16_t *val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = puffs_framebuf_getdata(pb, val, 2);
|
||||
LE16TOH(*val);
|
||||
|
||||
ERETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
p9pbuf_get_4(struct puffs_framebuf *pb, uint32_t *val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = puffs_framebuf_getdata(pb, val, 4);
|
||||
LE32TOH(*val);
|
||||
|
||||
ERETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
p9pbuf_get_8(struct puffs_framebuf *pb, uint64_t *val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = puffs_framebuf_getdata(pb, val, 8);
|
||||
LE64TOH(*val);
|
||||
|
||||
ERETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
p9pbuf_get_data(struct puffs_framebuf *pb, uint8_t **dp, uint16_t *dlenp)
|
||||
{
|
||||
uint8_t *data;
|
||||
uint16_t len;
|
||||
int rv;
|
||||
|
||||
rv = p9pbuf_get_2(pb, &len);
|
||||
if (rv)
|
||||
return errno;
|
||||
|
||||
if (puffs_framebuf_remaining(pb) < len)
|
||||
return EPROTO;
|
||||
|
||||
if (dp) {
|
||||
data = emalloc(len+1);
|
||||
rv = puffs_framebuf_getdata(pb, data, len);
|
||||
if (rv) {
|
||||
free(data);
|
||||
return errno;
|
||||
}
|
||||
data[len] = '\0';
|
||||
*dp = data;
|
||||
} else
|
||||
puffs_framebuf_seekset(pb, puffs_framebuf_telloff(pb)+len);
|
||||
|
||||
if (dlenp)
|
||||
*dlenp = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
p9pbuf_read_data(struct puffs_framebuf *pb, uint8_t *buf, uint32_t dlen)
|
||||
{
|
||||
|
||||
ERETURN(puffs_framebuf_getdata(pb, buf, dlen));
|
||||
}
|
||||
|
||||
int
|
||||
p9pbuf_get_str(struct puffs_framebuf *pb, char **dp, uint16_t *dlenp)
|
||||
{
|
||||
|
||||
return p9pbuf_get_data(pb, (uint8_t **)dp, dlenp);
|
||||
}
|
||||
365
usr.sbin/puffs/mount_9p/nineproto.c
Normal file
365
usr.sbin/puffs/mount_9p/nineproto.c
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
/* $NetBSD: nineproto.c,v 1.9 2007/11/30 19:02:38 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: nineproto.c,v 1.9 2007/11/30 19:02:38 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <puffs.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ninepuffs.h"
|
||||
#include "nineproto.h"
|
||||
|
||||
int
|
||||
proto_getqid(struct puffs_framebuf *pb, struct qid9p *qid)
|
||||
{
|
||||
|
||||
if (puffs_framebuf_remaining(pb) < 1+4+8)
|
||||
return ENOBUFS;
|
||||
|
||||
p9pbuf_get_1(pb, &qid->qidtype);
|
||||
p9pbuf_get_4(pb, &qid->qidvers);
|
||||
p9pbuf_get_8(pb, &qid->qidpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uid_t
|
||||
ustr2uid(char *uid)
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
pw = getpwnam(uid);
|
||||
if (pw == NULL)
|
||||
return 0; /* XXXXX */
|
||||
|
||||
return pw->pw_uid;
|
||||
}
|
||||
|
||||
static gid_t
|
||||
gstr2gid(char *gid)
|
||||
{
|
||||
struct group *grr;
|
||||
|
||||
grr = getgrnam(gid);
|
||||
if (grr == NULL)
|
||||
return 0; /* more XXXX */
|
||||
|
||||
return grr->gr_gid;
|
||||
}
|
||||
|
||||
static const char *
|
||||
uid2ustr(uid_t uid)
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
pw = getpwuid(uid);
|
||||
if (pw == NULL)
|
||||
return "root"; /* XXXXX */
|
||||
|
||||
return pw->pw_name;
|
||||
}
|
||||
|
||||
static const char *
|
||||
gid2gstr(gid_t gid)
|
||||
{
|
||||
struct group *grr;
|
||||
|
||||
grr = getgrgid(gid);
|
||||
if (grr == NULL)
|
||||
return "wheel"; /* XXXXXX */
|
||||
|
||||
return grr->gr_name;
|
||||
}
|
||||
|
||||
#define GETFIELD(a,b,unitsize) \
|
||||
do { \
|
||||
if (size < unitsize) return EPROTO; \
|
||||
if ((rv = (a(pb, b)))) return rv; \
|
||||
size -= unitsize; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define GETSTR(val,strsize) \
|
||||
do { \
|
||||
if ((rv = p9pbuf_get_str(pb, val, strsize))) return rv; \
|
||||
if (*strsize > size) return EPROTO; \
|
||||
size -= *strsize; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
int
|
||||
proto_getstat(struct puffs_framebuf *pb, struct vattr *vap,
|
||||
char **name, uint16_t *rs)
|
||||
{
|
||||
char *uid, *gid;
|
||||
struct qid9p qid;
|
||||
uint64_t flen;
|
||||
uint32_t rdev, mode, atime, mtime;
|
||||
uint16_t size, v16;
|
||||
int rv;
|
||||
|
||||
/* check size */
|
||||
if ((rv = p9pbuf_get_2(pb, &size)))
|
||||
return rv;
|
||||
if (puffs_framebuf_remaining(pb) < size)
|
||||
return ENOBUFS;
|
||||
|
||||
if (rs)
|
||||
*rs = size+2; /* compensate for size field itself */
|
||||
|
||||
GETFIELD(p9pbuf_get_2, &v16, 2);
|
||||
if (v16)
|
||||
printf("%d\n", v16);
|
||||
GETFIELD(p9pbuf_get_4, &rdev, 4);
|
||||
GETFIELD(proto_getqid, &qid, 13);
|
||||
GETFIELD(p9pbuf_get_4, &mode, 4);
|
||||
GETFIELD(p9pbuf_get_4, &atime, 4);
|
||||
GETFIELD(p9pbuf_get_4, &mtime, 4);
|
||||
GETFIELD(p9pbuf_get_8, &flen, 8);
|
||||
GETSTR(name, &v16);
|
||||
GETSTR(&uid, &v16);
|
||||
GETSTR(&gid, &v16);
|
||||
|
||||
if (rdev)
|
||||
printf("%d\n", rdev);
|
||||
vap->va_rdev = rdev;
|
||||
vap->va_mode = mode & 0777; /* may contain other uninteresting bits */
|
||||
vap->va_atime.tv_sec = atime;
|
||||
vap->va_mtime.tv_sec = mtime;
|
||||
vap->va_ctime.tv_sec = mtime;
|
||||
vap->va_atime.tv_nsec=vap->va_mtime.tv_nsec=vap->va_ctime.tv_nsec = 0;
|
||||
vap->va_birthtime.tv_sec = vap->va_birthtime.tv_nsec = 0;
|
||||
vap->va_size = vap->va_bytes = flen;
|
||||
vap->va_uid = ustr2uid(uid);
|
||||
vap->va_gid = gstr2gid(gid);
|
||||
free(uid);
|
||||
free(gid);
|
||||
qid2vattr(vap, &qid);
|
||||
|
||||
/* some defaults */
|
||||
if (vap->va_type == VDIR)
|
||||
vap->va_nlink = 1906;
|
||||
else
|
||||
vap->va_nlink = 1;
|
||||
vap->va_blocksize = 512;
|
||||
vap->va_flags = vap->va_vaflags = 0;
|
||||
vap->va_filerev = PUFFS_VNOVAL;
|
||||
|
||||
/* muid, not used */
|
||||
GETSTR(NULL, &v16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
proto_cc_dupfid(struct puffs_usermount *pu, p9pfid_t oldfid, p9pfid_t newfid)
|
||||
{
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu);
|
||||
struct puffs9p *p9p = puffs_getspecific(pu);
|
||||
struct puffs_framebuf *pb;
|
||||
p9ptag_t tag = NEXTTAG(p9p);
|
||||
uint16_t qids;
|
||||
int rv = 0;
|
||||
|
||||
pb = p9pbuf_makeout();
|
||||
p9pbuf_put_1(pb, P9PROTO_T_WALK);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, oldfid);
|
||||
p9pbuf_put_4(pb, newfid);
|
||||
p9pbuf_put_2(pb, 0);
|
||||
GETRESPONSE(pb);
|
||||
|
||||
rv = proto_expect_walk_nqids(pb, &qids);
|
||||
if (rv == 0 && qids != 0)
|
||||
rv = EPROTO;
|
||||
|
||||
out:
|
||||
puffs_framebuf_destroy(pb);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
proto_cc_clunkfid(struct puffs_usermount *pu, p9pfid_t fid, int waitforit)
|
||||
{
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu);
|
||||
struct puffs9p *p9p = puffs_getspecific(pu);
|
||||
struct puffs_framebuf *pb;
|
||||
p9ptag_t tag = NEXTTAG(p9p);
|
||||
int rv = 0;
|
||||
|
||||
pb = p9pbuf_makeout();
|
||||
p9pbuf_put_1(pb, P9PROTO_T_CLUNK);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, fid);
|
||||
|
||||
if (waitforit) {
|
||||
if (puffs_framev_enqueue_cc(pcc, p9p->servsock, pb, 0) == 0) {
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_CLUNK)
|
||||
rv = EPROTO;
|
||||
} else {
|
||||
rv = errno;
|
||||
}
|
||||
puffs_framebuf_destroy(pb);
|
||||
} else {
|
||||
JUSTSEND(pb);
|
||||
}
|
||||
|
||||
out:
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* walk a new fid, then open it
|
||||
*/
|
||||
int
|
||||
proto_cc_open(struct puffs_usermount *pu, p9pfid_t fid,
|
||||
p9pfid_t newfid, int mode)
|
||||
{
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu);
|
||||
struct puffs9p *p9p = puffs_getspecific(pu);
|
||||
struct puffs_framebuf *pb;
|
||||
p9ptag_t tag = NEXTTAG(p9p);
|
||||
int rv;
|
||||
|
||||
rv = proto_cc_dupfid(pu, fid, newfid);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
pb = p9pbuf_makeout();
|
||||
p9pbuf_put_1(pb, P9PROTO_T_OPEN);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, newfid);
|
||||
p9pbuf_put_1(pb, mode);
|
||||
GETRESPONSE(pb);
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_OPEN)
|
||||
rv = EPROTO;
|
||||
|
||||
out:
|
||||
puffs_framebuf_destroy(pb);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
proto_make_stat(struct puffs_framebuf *pb, const struct vattr *vap,
|
||||
const char *filename, enum vtype vt)
|
||||
{
|
||||
struct vattr fakeva;
|
||||
uint32_t mode, atime, mtime;
|
||||
uint64_t flen;
|
||||
const char *owner, *group;
|
||||
int startoff, curoff;
|
||||
|
||||
if (vap == NULL) {
|
||||
puffs_vattr_null(&fakeva);
|
||||
vap = &fakeva;
|
||||
}
|
||||
|
||||
startoff = puffs_framebuf_telloff(pb);
|
||||
puffs_framebuf_seekset(pb, startoff + 2+2); /* stat[n] incl. stat[2] */
|
||||
|
||||
if (vap->va_mode != (mode_t)PUFFS_VNOVAL)
|
||||
mode = vap->va_mode | (vt == VDIR ? P9PROTO_CPERM_DIR : 0);
|
||||
else
|
||||
mode = P9PROTO_STAT_NOVAL4;
|
||||
if (vap->va_atime.tv_sec != (time_t)PUFFS_VNOVAL)
|
||||
atime = vap->va_atime.tv_sec;
|
||||
else
|
||||
atime = P9PROTO_STAT_NOVAL4;
|
||||
if (vap->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL)
|
||||
mtime = vap->va_mtime.tv_sec;
|
||||
else
|
||||
mtime = P9PROTO_STAT_NOVAL4;
|
||||
if (vap->va_size != (u_quad_t)PUFFS_VNOVAL)
|
||||
flen = vap->va_size;
|
||||
else
|
||||
flen = P9PROTO_STAT_NOVAL8;
|
||||
if (vap->va_uid != (uid_t)PUFFS_VNOVAL)
|
||||
owner = uid2ustr(vap->va_uid);
|
||||
else
|
||||
owner = "";
|
||||
if (vap->va_gid != (gid_t)PUFFS_VNOVAL)
|
||||
group = gid2gstr(vap->va_gid);
|
||||
else
|
||||
group = "";
|
||||
|
||||
p9pbuf_put_2(pb, P9PROTO_STAT_NOVAL2); /* kernel type */
|
||||
p9pbuf_put_4(pb, P9PROTO_STAT_NOVAL4); /* dev */
|
||||
p9pbuf_put_1(pb, P9PROTO_STAT_NOVAL1); /* type */
|
||||
p9pbuf_put_4(pb, P9PROTO_STAT_NOVAL4); /* version */
|
||||
p9pbuf_put_8(pb, P9PROTO_STAT_NOVAL8); /* path */
|
||||
p9pbuf_put_4(pb, mode);
|
||||
p9pbuf_put_4(pb, atime);
|
||||
p9pbuf_put_4(pb, mtime);
|
||||
p9pbuf_put_8(pb, flen);
|
||||
p9pbuf_put_str(pb, filename ? filename : "");
|
||||
p9pbuf_put_str(pb, owner);
|
||||
p9pbuf_put_str(pb, group);
|
||||
p9pbuf_put_str(pb, ""); /* muid */
|
||||
|
||||
curoff = puffs_framebuf_telloff(pb);
|
||||
puffs_framebuf_seekset(pb, startoff);
|
||||
p9pbuf_put_2(pb, curoff-(startoff+2)); /* stat[n] size */
|
||||
p9pbuf_put_2(pb, curoff-(startoff+4)); /* size[2] stat */
|
||||
|
||||
puffs_framebuf_seekset(pb, curoff);
|
||||
}
|
||||
|
||||
int
|
||||
proto_expect_walk_nqids(struct puffs_framebuf *pb, uint16_t *nqids)
|
||||
{
|
||||
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_WALK)
|
||||
return EPROTO;
|
||||
return p9pbuf_get_2(pb, nqids);
|
||||
}
|
||||
|
||||
int
|
||||
proto_expect_qid(struct puffs_framebuf *pb, uint8_t op, struct qid9p *qid)
|
||||
{
|
||||
|
||||
if (p9pbuf_get_type(pb) != op)
|
||||
return EPROTO;
|
||||
return proto_getqid(pb, qid);
|
||||
}
|
||||
|
||||
int
|
||||
proto_expect_stat(struct puffs_framebuf *pb, struct vattr *va)
|
||||
{
|
||||
uint16_t dummy;
|
||||
int rv;
|
||||
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_STAT)
|
||||
return EPROTO;
|
||||
if ((rv = p9pbuf_get_2(pb, &dummy)))
|
||||
return rv;
|
||||
return proto_getstat(pb, va, NULL, NULL);
|
||||
}
|
||||
93
usr.sbin/puffs/mount_9p/nineproto.h
Normal file
93
usr.sbin/puffs/mount_9p/nineproto.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/* $NetBSD: nineproto.h,v 1.1 2007/04/21 14:21:43 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef PUFFS9P_9PROTO_H_
|
||||
#define PUFFS9P_9PROTO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define P9PROTO_VERSION "9P2000"
|
||||
|
||||
#define P9PROTO_T_VERSION 100
|
||||
#define P9PROTO_R_VERSION 101
|
||||
#define P9PROTO_T_AUTH 102
|
||||
#define P9PROTO_R_AUTH 103
|
||||
#define P9PROTO_T_ATTACH 104
|
||||
#define P9PROTO_R_ATTACH 105
|
||||
#define P9PROTO_T_ERROR 106
|
||||
#define P9PROTO_R_ERROR 107
|
||||
#define P9PROTO_T_FLUSH 108
|
||||
#define P9PROTO_R_FLUSH 109
|
||||
#define P9PROTO_T_WALK 110
|
||||
#define P9PROTO_R_WALK 111
|
||||
#define P9PROTO_T_OPEN 112
|
||||
#define P9PROTO_R_OPEN 113
|
||||
#define P9PROTO_T_CREATE 114
|
||||
#define P9PROTO_R_CREATE 115
|
||||
#define P9PROTO_T_READ 116
|
||||
#define P9PROTO_R_READ 117
|
||||
#define P9PROTO_T_WRITE 118
|
||||
#define P9PROTO_R_WRITE 119
|
||||
#define P9PROTO_T_CLUNK 120
|
||||
#define P9PROTO_R_CLUNK 121
|
||||
#define P9PROTO_T_REMOVE 122
|
||||
#define P9PROTO_R_REMOVE 123
|
||||
#define P9PROTO_T_STAT 124
|
||||
#define P9PROTO_R_STAT 125
|
||||
#define P9PROTO_T_WSTAT 126
|
||||
#define P9PROTO_R_WSTAT 127
|
||||
#define P9PROTO_MIN 9PROTO_T_VERSION
|
||||
#define P9PROTO_MAX 9PROTO_R_MAX
|
||||
|
||||
#define P9PROTO_NOFID (uint32_t)~0
|
||||
#define P9PROTO_NOTAG (uint16_t)~0
|
||||
|
||||
/* type field in a qid */
|
||||
#define P9PROTO_QID_TYPE_DIR 0x80
|
||||
#define P9PROTO_QID_TYPE_APPEND 0x40
|
||||
#define P9PROTO_QID_TYPE_EXCL 0x20
|
||||
#define P9PROTO_QID_TYPE_MOUNT 0x10
|
||||
#define P9PROTO_QID_TYPE_AUTH 0x08
|
||||
|
||||
/* mode in open */
|
||||
#define P9PROTO_OMODE_READ 0x00
|
||||
#define P9PROTO_OMODE_WRITE 0x01
|
||||
#define P9PROTO_OMODE_RDWR 0x02
|
||||
#define P9PROTO_OMODE_EXEC 0x03
|
||||
#define P9PROTO_OMODE_TRUNC 0x10
|
||||
#define P9PROTO_OMODE_RMCLOSE 0x40
|
||||
|
||||
/* for creating directories */
|
||||
#define P9PROTO_CPERM_DIR 0x80000000
|
||||
|
||||
/* stat non-values */
|
||||
#define P9PROTO_STAT_NOVAL1 (uint8_t)~0
|
||||
#define P9PROTO_STAT_NOVAL2 (uint16_t)~0
|
||||
#define P9PROTO_STAT_NOVAL4 (uint32_t)~0
|
||||
#define P9PROTO_STAT_NOVAL8 (uint64_t)~0
|
||||
|
||||
#endif /* PUFFS9P_PROTO_H_ */
|
||||
231
usr.sbin/puffs/mount_9p/ninepuffs.c
Normal file
231
usr.sbin/puffs/mount_9p/ninepuffs.c
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/* $NetBSD: ninepuffs.c,v 1.24 2011/08/31 13:32:39 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 9puffs: access a 9P file server as a vfs via puffs
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ninepuffs.c,v 1.24 2011/08/31 13:32:39 joerg Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/poll.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <puffs.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ninepuffs.h"
|
||||
|
||||
#define DEFPORT_9P 564
|
||||
|
||||
__dead static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: %s [-s] [-o mntopts] [-p port] "
|
||||
"[user@]server[:path] mountpoint\n", getprogname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* TCPv4 connection to 9P file server, forget IL and IPv6 for now.
|
||||
* Return connected socket or exit with error.
|
||||
*/
|
||||
static int
|
||||
serverconnect(const char *addr, unsigned short port)
|
||||
{
|
||||
struct sockaddr_in mysin;
|
||||
struct hostent *he;
|
||||
int s;
|
||||
|
||||
he = gethostbyname2(addr, AF_INET);
|
||||
if (he == NULL) {
|
||||
herror("gethostbyname");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (s == -1)
|
||||
err(1, "socket");
|
||||
|
||||
memset(&mysin, 0, sizeof(struct sockaddr_in));
|
||||
mysin.sin_family = AF_INET;
|
||||
mysin.sin_port = htons(port);
|
||||
memcpy(&mysin.sin_addr, he->h_addr, sizeof(struct in_addr));
|
||||
|
||||
if (connect(s, (struct sockaddr *)&mysin, sizeof(mysin)) == -1)
|
||||
err(1, "connect");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct puffs9p p9p;
|
||||
struct puffs_usermount *pu;
|
||||
struct puffs_ops *pops;
|
||||
struct puffs_node *pn_root;
|
||||
mntoptparse_t mp;
|
||||
const char *user, *srvhost, *srvpath;
|
||||
char *p;
|
||||
unsigned short port;
|
||||
int mntflags, pflags, ch;
|
||||
int detach;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
mntflags = pflags = 0;
|
||||
detach = 1;
|
||||
port = DEFPORT_9P;
|
||||
|
||||
while ((ch = getopt(argc, argv, "o:p:s")) != -1) {
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags);
|
||||
if (mp == NULL)
|
||||
err(1, "getmntopts");
|
||||
freemntopts(mp);
|
||||
break;
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
detach = 0;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 2)
|
||||
usage();
|
||||
|
||||
if (pflags & PUFFS_FLAG_OPDUMP)
|
||||
detach = 0;
|
||||
pflags |= PUFFS_KFLAG_WTCACHE | PUFFS_KFLAG_IAONDEMAND;
|
||||
|
||||
PUFFSOP_INIT(pops);
|
||||
|
||||
PUFFSOP_SET(pops, puffs9p, fs, unmount);
|
||||
PUFFSOP_SETFSNOP(pops, sync);
|
||||
PUFFSOP_SETFSNOP(pops, statvfs);
|
||||
|
||||
PUFFSOP_SET(pops, puffs9p, node, lookup);
|
||||
PUFFSOP_SET(pops, puffs9p, node, readdir);
|
||||
PUFFSOP_SET(pops, puffs9p, node, getattr);
|
||||
PUFFSOP_SET(pops, puffs9p, node, setattr);
|
||||
PUFFSOP_SET(pops, puffs9p, node, create);
|
||||
PUFFSOP_SET(pops, puffs9p, node, open);
|
||||
PUFFSOP_SET(pops, puffs9p, node, mkdir);
|
||||
PUFFSOP_SET(pops, puffs9p, node, remove);
|
||||
PUFFSOP_SET(pops, puffs9p, node, rmdir);
|
||||
PUFFSOP_SET(pops, puffs9p, node, read);
|
||||
PUFFSOP_SET(pops, puffs9p, node, write);
|
||||
PUFFSOP_SET(pops, puffs9p, node, rename);
|
||||
PUFFSOP_SET(pops, puffs9p, node, inactive);
|
||||
PUFFSOP_SET(pops, puffs9p, node, reclaim);
|
||||
#if 0
|
||||
PUFFSOP_SET(pops, puffs9p, node, mknod);
|
||||
#endif
|
||||
|
||||
pu = puffs_init(pops, argv[0], "9p", &p9p, pflags);
|
||||
if (pu == NULL)
|
||||
err(1, "puffs_init");
|
||||
|
||||
memset(&p9p, 0, sizeof(p9p));
|
||||
p9p.maxreq = P9P_DEFREQLEN;
|
||||
p9p.nextfid = 1;
|
||||
|
||||
/* user@ */
|
||||
if ((p = strchr(argv[0], '@')) != NULL) {
|
||||
*p = '\0';
|
||||
srvhost = p+1;
|
||||
user = argv[0];
|
||||
} else {
|
||||
struct passwd *pw;
|
||||
|
||||
srvhost = argv[0];
|
||||
pw = getpwuid(getuid());
|
||||
if (pw == NULL)
|
||||
err(1, "getpwuid");
|
||||
user = pw->pw_name;
|
||||
}
|
||||
|
||||
/* :/mountpath */
|
||||
if ((p = strchr(srvhost, ':')) != NULL) {
|
||||
*p = '\0';
|
||||
srvpath = p+1;
|
||||
if (*srvpath != '/')
|
||||
errx(1, "%s is not an absolute path", srvpath);
|
||||
} else {
|
||||
srvpath = "/";
|
||||
}
|
||||
|
||||
p9p.servsock = serverconnect(srvhost, port);
|
||||
if ((pn_root = p9p_handshake(pu, user, srvpath)) == NULL) {
|
||||
puffs_exit(pu, 1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
puffs_framev_init(pu, p9pbuf_read, p9pbuf_write, p9pbuf_cmp, NULL,
|
||||
puffs_framev_unmountonclose);
|
||||
if (puffs_framev_addfd(pu, p9p.servsock,
|
||||
PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
|
||||
err(1, "puffs_framebuf_addfd");
|
||||
|
||||
if (detach)
|
||||
if (puffs_daemon(pu, 1, 1) == -1)
|
||||
err(1, "puffs_daemon");
|
||||
|
||||
if (puffs_mount(pu, argv[1], mntflags, pn_root) == -1)
|
||||
err(1, "puffs_mount");
|
||||
if (puffs_setblockingmode(pu, PUFFSDEV_NONBLOCK) == -1)
|
||||
err(1, "setblockingmode");
|
||||
|
||||
if (puffs_mainloop(pu) == -1)
|
||||
err(1, "mainloop");
|
||||
|
||||
return 0;
|
||||
}
|
||||
178
usr.sbin/puffs/mount_9p/ninepuffs.h
Normal file
178
usr.sbin/puffs/mount_9p/ninepuffs.h
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/* $NetBSD: ninepuffs.h,v 1.12 2007/11/30 19:02:38 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef PUFFS9P_H_
|
||||
#define PUFFS9P_H_
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <puffs.h>
|
||||
|
||||
PUFFSOP_PROTOS(puffs9p);
|
||||
|
||||
/* Qid structure. optimized for in-mem. different order on-wire */
|
||||
struct qid9p {
|
||||
uint64_t qidpath;
|
||||
uint32_t qidvers;
|
||||
uint8_t qidtype;
|
||||
};
|
||||
|
||||
typedef uint16_t p9ptag_t;
|
||||
typedef uint32_t p9pfid_t;
|
||||
|
||||
/*
|
||||
* refuse (no, not *that* refuse) to play if the server doesn't
|
||||
* support requests of at least the following size. It would only
|
||||
* make life difficult
|
||||
*/
|
||||
#define P9P_MINREQLEN 512
|
||||
|
||||
#define P9P_DEFREQLEN (16*1024)
|
||||
#define P9P_INVALFID 0
|
||||
#define P9P_ROOTFID 1
|
||||
|
||||
#define NEXTTAG(p9p) \
|
||||
((++(p9p->nexttag)) == P9PROTO_NOTAG ? p9p->nexttag = 0 : p9p->nexttag)
|
||||
|
||||
#define NEXTFID(p9p) \
|
||||
((++(p9p->nextfid)) == P9P_INVALFID ? p9p->nextfid = 2 : p9p->nextfid)
|
||||
|
||||
#define AUTOVAR(pu) \
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu); \
|
||||
struct puffs9p *p9p = puffs_getspecific(pu); \
|
||||
uint16_t tag = NEXTTAG(p9p); \
|
||||
struct puffs_framebuf *pb = p9pbuf_makeout(); \
|
||||
int rv = 0
|
||||
|
||||
#define RETURN(rv) \
|
||||
puffs_framebuf_destroy(pb); \
|
||||
return (rv)
|
||||
|
||||
#define GETRESPONSE(pb) \
|
||||
do { \
|
||||
if (puffs_framev_enqueue_cc(pcc, p9p->servsock, pb, 0) == -1) { \
|
||||
rv = errno; \
|
||||
goto out; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define JUSTSEND(pb) \
|
||||
do { \
|
||||
if (puffs_framev_enqueue_justsend(pu,p9p->servsock,pb,1,0)==-1){\
|
||||
rv = errno; \
|
||||
goto out; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SENDCB(pb, f, a) \
|
||||
do { \
|
||||
if (puffs_framev_enqueue_cb(pu, p9p->servsock,pb,f,a,0) == -1) {\
|
||||
rv = errno; \
|
||||
goto out; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
struct puffs9p {
|
||||
int servsock;
|
||||
|
||||
p9ptag_t nexttag;
|
||||
p9pfid_t nextfid;
|
||||
|
||||
size_t maxreq; /* negotiated with server */
|
||||
};
|
||||
|
||||
struct dirfid {
|
||||
p9pfid_t fid;
|
||||
off_t seekoff;
|
||||
LIST_ENTRY(dirfid) entries;
|
||||
};
|
||||
|
||||
struct p9pnode {
|
||||
p9pfid_t fid_base;
|
||||
p9pfid_t fid_read;
|
||||
p9pfid_t fid_write;
|
||||
|
||||
LIST_HEAD(,dirfid) dir_openlist;
|
||||
};
|
||||
|
||||
struct puffs_framebuf *p9pbuf_makeout(void);
|
||||
void p9pbuf_recycleout(struct puffs_framebuf *);
|
||||
|
||||
int p9pbuf_read(struct puffs_usermount *, struct puffs_framebuf *,int,int*);
|
||||
int p9pbuf_write(struct puffs_usermount *, struct puffs_framebuf*,int,int*);
|
||||
int p9pbuf_cmp(struct puffs_usermount *,
|
||||
struct puffs_framebuf *, struct puffs_framebuf *, int *);
|
||||
|
||||
void p9pbuf_put_1(struct puffs_framebuf *, uint8_t);
|
||||
void p9pbuf_put_2(struct puffs_framebuf *, uint16_t);
|
||||
void p9pbuf_put_4(struct puffs_framebuf *, uint32_t);
|
||||
void p9pbuf_put_8(struct puffs_framebuf *, uint64_t);
|
||||
void p9pbuf_put_str(struct puffs_framebuf *, const char *);
|
||||
void p9pbuf_put_data(struct puffs_framebuf *, const void *, uint16_t);
|
||||
void p9pbuf_write_data(struct puffs_framebuf *, uint8_t *, uint32_t);
|
||||
|
||||
int p9pbuf_get_1(struct puffs_framebuf *, uint8_t *);
|
||||
int p9pbuf_get_2(struct puffs_framebuf *, uint16_t *);
|
||||
int p9pbuf_get_4(struct puffs_framebuf *, uint32_t *);
|
||||
int p9pbuf_get_8(struct puffs_framebuf *, uint64_t *);
|
||||
int p9pbuf_get_str(struct puffs_framebuf *, char **, uint16_t *);
|
||||
int p9pbuf_get_data(struct puffs_framebuf *, uint8_t **, uint16_t *);
|
||||
int p9pbuf_read_data(struct puffs_framebuf *, uint8_t *, uint32_t);
|
||||
|
||||
uint8_t p9pbuf_get_type(struct puffs_framebuf *);
|
||||
uint16_t p9pbuf_get_tag(struct puffs_framebuf *);
|
||||
|
||||
int proto_getqid(struct puffs_framebuf *, struct qid9p *);
|
||||
int proto_getstat(struct puffs_framebuf *, struct vattr *,
|
||||
char **, uint16_t *);
|
||||
int proto_expect_walk_nqids(struct puffs_framebuf *, uint16_t *);
|
||||
int proto_expect_stat(struct puffs_framebuf *, struct vattr *);
|
||||
int proto_expect_qid(struct puffs_framebuf *, uint8_t, struct qid9p *);
|
||||
|
||||
int proto_cc_dupfid(struct puffs_usermount *, p9pfid_t, p9pfid_t);
|
||||
int proto_cc_clunkfid(struct puffs_usermount *, p9pfid_t, int);
|
||||
int proto_cc_open(struct puffs_usermount *, p9pfid_t, p9pfid_t, int);
|
||||
|
||||
void proto_make_stat(struct puffs_framebuf *, const struct vattr *,
|
||||
const char *, enum vtype);
|
||||
|
||||
struct puffs_node *p9p_handshake(struct puffs_usermount *,
|
||||
const char *, const char *);
|
||||
|
||||
void qid2vattr(struct vattr *, const struct qid9p *);
|
||||
struct puffs_node *newp9pnode_va(struct puffs_usermount *,
|
||||
const struct vattr *, p9pfid_t);
|
||||
struct puffs_node *newp9pnode_qid(struct puffs_usermount *,
|
||||
const struct qid9p *, p9pfid_t);
|
||||
|
||||
int getdfwithoffset(struct puffs_usermount *, struct p9pnode *, off_t,
|
||||
struct dirfid **);
|
||||
void storedf(struct p9pnode *, struct dirfid *);
|
||||
void releasedf(struct puffs_usermount *, struct dirfid *);
|
||||
void nukealldf(struct puffs_usermount *, struct p9pnode *);
|
||||
|
||||
#endif /* PUFFS9P_H_ */
|
||||
616
usr.sbin/puffs/mount_9p/node.c
Normal file
616
usr.sbin/puffs/mount_9p/node.c
Normal file
|
|
@ -0,0 +1,616 @@
|
|||
/* $NetBSD: node.c,v 1.21 2009/01/18 10:10:47 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: node.c,v 1.21 2009/01/18 10:10:47 lukem Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <puffs.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ninepuffs.h"
|
||||
#include "nineproto.h"
|
||||
|
||||
static void *
|
||||
nodecmp(struct puffs_usermount *pu, struct puffs_node *pn, void *arg)
|
||||
{
|
||||
struct vattr *vap = &pn->pn_va;
|
||||
struct qid9p *qid = arg;
|
||||
|
||||
if (vap->va_fileid == qid->qidpath && vap->va_gen == qid->qidvers)
|
||||
return pn;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
do_getattr(struct puffs_usermount *pu, struct puffs_node *pn, struct vattr *vap)
|
||||
{
|
||||
AUTOVAR(pu);
|
||||
struct p9pnode *p9n = pn->pn_data;
|
||||
|
||||
p9pbuf_put_1(pb, P9PROTO_T_STAT);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, p9n->fid_base);
|
||||
GETRESPONSE(pb);
|
||||
|
||||
rv = proto_expect_stat(pb, vap);
|
||||
|
||||
out:
|
||||
RETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_node_getattr(struct puffs_usermount *pu, void *opc, struct vattr *vap,
|
||||
const struct puffs_cred *pcr)
|
||||
{
|
||||
struct puffs_node *pn = opc;
|
||||
int rv;
|
||||
|
||||
rv = do_getattr(pu, pn, &pn->pn_va);
|
||||
if (rv == 0)
|
||||
memcpy(vap, &pn->pn_va, sizeof(struct vattr));
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_node_lookup(struct puffs_usermount *pu, void *opc, struct puffs_newinfo *pni,
|
||||
const struct puffs_cn *pcn)
|
||||
{
|
||||
AUTOVAR(pu);
|
||||
struct vattr va;
|
||||
struct puffs_node *pn, *pn_dir = opc;
|
||||
struct p9pnode *p9n_dir = pn_dir->pn_data;
|
||||
p9ptag_t tfid = NEXTFID(p9p);
|
||||
struct qid9p newqid;
|
||||
uint16_t nqid;
|
||||
|
||||
p9pbuf_put_1(pb, P9PROTO_T_WALK);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, p9n_dir->fid_base);
|
||||
p9pbuf_put_4(pb, tfid);
|
||||
p9pbuf_put_2(pb, 1);
|
||||
p9pbuf_put_str(pb, pcn->pcn_name);
|
||||
GETRESPONSE(pb);
|
||||
|
||||
rv = proto_expect_walk_nqids(pb, &nqid);
|
||||
if (rv) {
|
||||
rv = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
if (nqid != 1) {
|
||||
rv = EPROTO;
|
||||
goto out;
|
||||
}
|
||||
if ((rv = proto_getqid(pb, &newqid)))
|
||||
goto out;
|
||||
|
||||
/* we get the parent vers in walk(?) compensate */
|
||||
p9pbuf_recycleout(pb);
|
||||
tag = NEXTTAG(p9p);
|
||||
p9pbuf_put_1(pb, P9PROTO_T_STAT);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, tfid);
|
||||
GETRESPONSE(pb);
|
||||
if ((rv = proto_expect_stat(pb, &va)) != 0) {
|
||||
proto_cc_clunkfid(pu, tfid, 0);
|
||||
rv = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
if (newqid.qidpath != va.va_fileid) {
|
||||
proto_cc_clunkfid(pu, tfid, 0);
|
||||
rv = EPROTO;
|
||||
goto out;
|
||||
}
|
||||
newqid.qidvers = va.va_gen;
|
||||
|
||||
pn = puffs_pn_nodewalk(pu, nodecmp, &newqid);
|
||||
if (pn == NULL)
|
||||
pn = newp9pnode_qid(pu, &newqid, tfid);
|
||||
else
|
||||
proto_cc_clunkfid(pu, tfid, 0);
|
||||
/* assert pn */
|
||||
memcpy(&pn->pn_va, &va, sizeof(va));
|
||||
|
||||
puffs_newinfo_setcookie(pni, pn);
|
||||
puffs_newinfo_setvtype(pni, pn->pn_va.va_type);
|
||||
puffs_newinfo_setsize(pni, pn->pn_va.va_size);
|
||||
puffs_newinfo_setrdev(pni, pn->pn_va.va_rdev);
|
||||
|
||||
out:
|
||||
RETURN(rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Problem is that 9P doesn't allow seeking into a directory. So we
|
||||
* maintain a list of active fids for any given directory. They
|
||||
* start living at the first read and exist either until the directory
|
||||
* is closed or until they reach the end.
|
||||
*/
|
||||
int
|
||||
puffs9p_node_readdir(struct puffs_usermount *pu, void *opc, struct dirent *dent,
|
||||
off_t *readoff, size_t *reslen, const struct puffs_cred *pcr,
|
||||
int *eofflag, off_t *cookies, size_t *ncookies)
|
||||
{
|
||||
AUTOVAR(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct p9pnode *p9n = pn->pn_data;
|
||||
struct vattr va;
|
||||
struct dirfid *dfp;
|
||||
char *name;
|
||||
uint32_t count;
|
||||
uint16_t statsize;
|
||||
|
||||
rv = getdfwithoffset(pu, p9n, *readoff, &dfp);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
tag = NEXTTAG(p9p);
|
||||
p9pbuf_put_1(pb, P9PROTO_T_READ);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, dfp->fid);
|
||||
p9pbuf_put_8(pb, *readoff);
|
||||
p9pbuf_put_4(pb, *reslen); /* XXX */
|
||||
GETRESPONSE(pb);
|
||||
|
||||
p9pbuf_get_4(pb, &count);
|
||||
|
||||
/*
|
||||
* if count is 0, assume we at end-of-dir. dfp is no longer
|
||||
* useful, so nuke it
|
||||
*/
|
||||
if (count == 0) {
|
||||
*eofflag = 1;
|
||||
releasedf(pu, dfp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (count > 0) {
|
||||
if ((rv = proto_getstat(pb, &va, &name, &statsize))) {
|
||||
/*
|
||||
* If there was an error, it's unlikely we'll be
|
||||
* coming back, so just nuke the dfp. If we do
|
||||
* come back for some strange reason, we'll just
|
||||
* regen it.
|
||||
*/
|
||||
releasedf(pu, dfp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
puffs_nextdent(&dent, name, va.va_fileid,
|
||||
puffs_vtype2dt(va.va_type), reslen);
|
||||
|
||||
count -= statsize;
|
||||
*readoff += statsize;
|
||||
dfp->seekoff += statsize;
|
||||
free(name);
|
||||
}
|
||||
|
||||
storedf(p9n, dfp);
|
||||
|
||||
out:
|
||||
RETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_node_setattr(struct puffs_usermount *pu, void *opc,
|
||||
const struct vattr *va, const struct puffs_cred *pcr)
|
||||
{
|
||||
AUTOVAR(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct p9pnode *p9n = pn->pn_data;
|
||||
|
||||
p9pbuf_put_1(pb, P9PROTO_T_WSTAT);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, p9n->fid_base);
|
||||
proto_make_stat(pb, va, NULL, pn->pn_va.va_type);
|
||||
GETRESPONSE(pb);
|
||||
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_WSTAT)
|
||||
rv = EPROTO;
|
||||
|
||||
out:
|
||||
RETURN(rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok, time to get clever. There are two possible cases: we are
|
||||
* opening a file or we are opening a directory.
|
||||
*
|
||||
* If it's a directory, don't bother opening it here, but rather
|
||||
* wait until readdir, since it's probable we need to be able to
|
||||
* open a directory there in any case.
|
||||
*
|
||||
* If it's a regular file, open it here with whatever credentials
|
||||
* we happen to have. Let the upper layers of the kernel worry
|
||||
* about permission control.
|
||||
*/
|
||||
int
|
||||
puffs9p_node_open(struct puffs_usermount *pu, void *opc, int mode,
|
||||
const struct puffs_cred *pcr)
|
||||
{
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu);
|
||||
struct puffs9p *p9p = puffs_getspecific(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct p9pnode *p9n = pn->pn_data;
|
||||
p9pfid_t nfid;
|
||||
int error = 0;
|
||||
|
||||
puffs_setback(pcc, PUFFS_SETBACK_INACT_N1);
|
||||
if (pn->pn_va.va_type != VDIR) {
|
||||
if (mode & FREAD && p9n->fid_read == P9P_INVALFID) {
|
||||
nfid = NEXTFID(p9p);
|
||||
error = proto_cc_open(pu, p9n->fid_base, nfid,
|
||||
P9PROTO_OMODE_READ);
|
||||
if (error)
|
||||
return error;
|
||||
p9n->fid_read = nfid;
|
||||
}
|
||||
if (mode & FWRITE && p9n->fid_write == P9P_INVALFID) {
|
||||
nfid = NEXTFID(p9p);
|
||||
error = proto_cc_open(pu, p9n->fid_base, nfid,
|
||||
P9PROTO_OMODE_WRITE);
|
||||
if (error)
|
||||
return error;
|
||||
p9n->fid_write = nfid;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_node_inactive(struct puffs_usermount *pu, void *opc)
|
||||
{
|
||||
struct puffs_node *pn = opc;
|
||||
struct p9pnode *p9n = pn->pn_data;
|
||||
|
||||
if (pn->pn_va.va_type == VDIR) {
|
||||
nukealldf(pu, p9n);
|
||||
} else {
|
||||
if (p9n->fid_read != P9P_INVALFID) {
|
||||
proto_cc_clunkfid(pu, p9n->fid_read, 0);
|
||||
p9n->fid_read = P9P_INVALFID;
|
||||
}
|
||||
if (p9n->fid_write != P9P_INVALFID) {
|
||||
proto_cc_clunkfid(pu, p9n->fid_write, 0);
|
||||
p9n->fid_write = P9P_INVALFID;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_node_read(struct puffs_usermount *pu, void *opc, uint8_t *buf,
|
||||
off_t offset, size_t *resid, const struct puffs_cred *pcr,
|
||||
int ioflag)
|
||||
{
|
||||
AUTOVAR(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct p9pnode *p9n = pn->pn_data;
|
||||
uint32_t count;
|
||||
size_t nread;
|
||||
|
||||
nread = 0;
|
||||
while (*resid > 0 && (uint64_t)(offset+nread) < pn->pn_va.va_size) {
|
||||
p9pbuf_put_1(pb, P9PROTO_T_READ);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, p9n->fid_read);
|
||||
p9pbuf_put_8(pb, offset+nread);
|
||||
p9pbuf_put_4(pb, MIN((uint32_t)*resid,p9p->maxreq-24));
|
||||
GETRESPONSE(pb);
|
||||
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_READ) {
|
||||
rv = EPROTO;
|
||||
break;
|
||||
}
|
||||
|
||||
p9pbuf_get_4(pb, &count);
|
||||
if ((rv = p9pbuf_read_data(pb, buf + nread, count)))
|
||||
break;
|
||||
|
||||
if (count == 0)
|
||||
break;
|
||||
|
||||
*resid -= count;
|
||||
nread += count;
|
||||
|
||||
p9pbuf_recycleout(pb);
|
||||
}
|
||||
|
||||
out:
|
||||
RETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_node_write(struct puffs_usermount *pu, void *opc, uint8_t *buf,
|
||||
off_t offset, size_t *resid, const struct puffs_cred *cred,
|
||||
int ioflag)
|
||||
{
|
||||
AUTOVAR(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct p9pnode *p9n = pn->pn_data;
|
||||
uint32_t chunk, count;
|
||||
size_t nwrite;
|
||||
|
||||
if (ioflag & PUFFS_IO_APPEND)
|
||||
offset = pn->pn_va.va_size;
|
||||
|
||||
nwrite = 0;
|
||||
while (*resid > 0) {
|
||||
chunk = MIN(*resid, p9p->maxreq-32);
|
||||
|
||||
p9pbuf_put_1(pb, P9PROTO_T_WRITE);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, p9n->fid_write);
|
||||
p9pbuf_put_8(pb, offset+nwrite);
|
||||
p9pbuf_put_4(pb, chunk);
|
||||
p9pbuf_write_data(pb, buf+nwrite, chunk);
|
||||
GETRESPONSE(pb);
|
||||
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_WRITE) {
|
||||
rv = EPROTO;
|
||||
break;
|
||||
}
|
||||
|
||||
p9pbuf_get_4(pb, &count);
|
||||
*resid -= count;
|
||||
nwrite += count;
|
||||
|
||||
if (count != chunk) {
|
||||
rv = EPROTO;
|
||||
break;
|
||||
}
|
||||
|
||||
p9pbuf_recycleout(pb);
|
||||
}
|
||||
|
||||
out:
|
||||
RETURN(rv);
|
||||
}
|
||||
|
||||
static int
|
||||
nodecreate(struct puffs_usermount *pu, struct puffs_node *pn,
|
||||
struct puffs_newinfo *pni, const char *name,
|
||||
const struct vattr *vap, uint32_t dirbit)
|
||||
{
|
||||
AUTOVAR(pu);
|
||||
struct puffs_node *pn_new;
|
||||
struct p9pnode *p9n = pn->pn_data;
|
||||
p9pfid_t nfid = NEXTFID(p9p);
|
||||
struct qid9p nqid;
|
||||
int tries = 0;
|
||||
|
||||
again:
|
||||
if (++tries > 5) {
|
||||
rv = EPROTO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = proto_cc_dupfid(pu, p9n->fid_base, nfid);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
p9pbuf_put_1(pb, P9PROTO_T_CREATE);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, nfid);
|
||||
p9pbuf_put_str(pb, name);
|
||||
p9pbuf_put_4(pb, dirbit | (vap->va_mode & 0777));
|
||||
p9pbuf_put_1(pb, 0);
|
||||
GETRESPONSE(pb);
|
||||
|
||||
rv = proto_expect_qid(pb, P9PROTO_R_CREATE, &nqid);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Now, little problem here: create returns an *open* fid.
|
||||
* So, clunk it and walk the parent directory to get a fid
|
||||
* which is not open for I/O yet.
|
||||
*/
|
||||
proto_cc_clunkfid(pu, nfid, 0);
|
||||
nfid = NEXTFID(p9p);
|
||||
|
||||
p9pbuf_recycleout(pb);
|
||||
p9pbuf_put_1(pb, P9PROTO_T_WALK);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, p9n->fid_base);
|
||||
p9pbuf_put_4(pb, nfid);
|
||||
p9pbuf_put_2(pb, 1);
|
||||
p9pbuf_put_str(pb, name);
|
||||
GETRESPONSE(pb);
|
||||
|
||||
/*
|
||||
* someone removed it already? try again
|
||||
* note: this is kind of lose/lose
|
||||
*/
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_WALK)
|
||||
goto again;
|
||||
|
||||
pn_new = newp9pnode_va(pu, vap, nfid);
|
||||
qid2vattr(&pn_new->pn_va, &nqid);
|
||||
puffs_newinfo_setcookie(pni, pn_new);
|
||||
|
||||
out:
|
||||
RETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_node_create(struct puffs_usermount *pu, void *opc, struct puffs_newinfo *pni,
|
||||
const struct puffs_cn *pcn, const struct vattr *va)
|
||||
{
|
||||
|
||||
return nodecreate(pu, opc, pni, pcn->pcn_name, va, 0);
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_node_mkdir(struct puffs_usermount *pu, void *opc, struct puffs_newinfo *pni,
|
||||
const struct puffs_cn *pcn, const struct vattr *va)
|
||||
{
|
||||
|
||||
return nodecreate(pu, opc, pni, pcn->pcn_name,
|
||||
va, P9PROTO_CPERM_DIR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to be a bit clever again: the fid is clunked no matter if
|
||||
* the remove succeeds or not. Re-getting a fid would be way too
|
||||
* difficult in case the remove failed for a valid reason (directory
|
||||
* not empty etcetc.). So walk ourselves another fid to prod the
|
||||
* ice with.
|
||||
*/
|
||||
static int
|
||||
noderemove(struct puffs_usermount *pu, struct puffs_node *pn)
|
||||
{
|
||||
AUTOVAR(pu);
|
||||
struct p9pnode *p9n = pn->pn_data;
|
||||
p9pfid_t testfid = NEXTFID(p9p);
|
||||
|
||||
rv = proto_cc_dupfid(pu, p9n->fid_base, testfid);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
p9pbuf_put_1(pb, P9PROTO_T_REMOVE);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, testfid);
|
||||
|
||||
/*
|
||||
* XXX: error handling isn't very robust, but doom is impending
|
||||
* anyway, so just accept we're going belly up and play dead
|
||||
*/
|
||||
GETRESPONSE(pb);
|
||||
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_REMOVE) {
|
||||
rv = EPROTO;
|
||||
} else {
|
||||
proto_cc_clunkfid(pu, p9n->fid_base, 0);
|
||||
p9n->fid_base = P9P_INVALFID;
|
||||
puffs_pn_remove(pn);
|
||||
}
|
||||
|
||||
out:
|
||||
if (rv == 0)
|
||||
puffs_setback(pcc, PUFFS_SETBACK_NOREF_N2);
|
||||
|
||||
RETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_node_remove(struct puffs_usermount *pu, void *opc, void *targ,
|
||||
const struct puffs_cn *pcn)
|
||||
{
|
||||
struct puffs_node *pn = targ;
|
||||
|
||||
if (pn->pn_va.va_type == VDIR)
|
||||
return EISDIR;
|
||||
|
||||
return noderemove(pu, pn);
|
||||
}
|
||||
|
||||
int
|
||||
puffs9p_node_rmdir(struct puffs_usermount *pu, void *opc, void *targ,
|
||||
const struct puffs_cn *pcn)
|
||||
{
|
||||
struct puffs_node *pn = targ;
|
||||
|
||||
if (pn->pn_va.va_type != VDIR)
|
||||
return ENOTDIR;
|
||||
|
||||
return noderemove(pu, pn);
|
||||
}
|
||||
|
||||
/*
|
||||
* 9P supports renames only for files within a directory
|
||||
* from what I could tell. So just support in-directory renames
|
||||
* for now.
|
||||
*/
|
||||
int
|
||||
puffs9p_node_rename(struct puffs_usermount *pu, void *opc, void *src,
|
||||
const struct puffs_cn *pcn_src, void *targ_dir, void *targ,
|
||||
const struct puffs_cn *pcn_targ)
|
||||
{
|
||||
AUTOVAR(pu);
|
||||
struct puffs_node *pn_src = src;
|
||||
struct p9pnode *p9n_src = pn_src->pn_data;
|
||||
|
||||
if (opc != targ_dir) {
|
||||
rv = EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 9P doesn't allow to overwrite in rename */
|
||||
if (targ) {
|
||||
struct puffs_node *pn_targ = targ;
|
||||
|
||||
rv = noderemove(pu, pn_targ->pn_data);
|
||||
if (rv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
p9pbuf_put_1(pb, P9PROTO_T_WSTAT);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, p9n_src->fid_base);
|
||||
proto_make_stat(pb, NULL, pcn_targ->pcn_name, pn_src->pn_va.va_type);
|
||||
GETRESPONSE(pb);
|
||||
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_WSTAT)
|
||||
rv = EPROTO;
|
||||
|
||||
out:
|
||||
RETURN(rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* - "here's one"
|
||||
* - "9P"
|
||||
* ~ "i'm not dead"
|
||||
* - "you're not fooling anyone you know, you'll be stone dead in a minute
|
||||
* - "he says he's not quite dead"
|
||||
* - "isn't there anything you could do?"
|
||||
* - *clunk*!
|
||||
* - "thanks"
|
||||
*/
|
||||
int
|
||||
puffs9p_node_reclaim(struct puffs_usermount *pu, void *opc)
|
||||
{
|
||||
struct puffs_node *pn = opc;
|
||||
struct p9pnode *p9n = pn->pn_data;
|
||||
|
||||
assert(LIST_EMPTY(&p9n->dir_openlist));
|
||||
assert(p9n->fid_read == P9P_INVALFID && p9n->fid_write == P9P_INVALFID);
|
||||
|
||||
proto_cc_clunkfid(pu, p9n->fid_base, 0);
|
||||
free(p9n);
|
||||
puffs_pn_put(pn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
197
usr.sbin/puffs/mount_9p/subr.c
Normal file
197
usr.sbin/puffs/mount_9p/subr.c
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
/* $NetBSD: subr.c,v 1.6 2007/11/30 19:02:39 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: subr.c,v 1.6 2007/11/30 19:02:39 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include "ninepuffs.h"
|
||||
#include "nineproto.h"
|
||||
|
||||
void
|
||||
qid2vattr(struct vattr *vap, const struct qid9p *qid)
|
||||
{
|
||||
|
||||
vap->va_fileid = qid->qidpath;
|
||||
vap->va_gen = qid->qidvers;
|
||||
if (qid->qidtype & P9PROTO_QID_TYPE_DIR)
|
||||
vap->va_type = VDIR;
|
||||
else
|
||||
vap->va_type = VREG;
|
||||
}
|
||||
|
||||
static struct puffs_node *
|
||||
makep9pnode(struct puffs_usermount *pu, p9pfid_t fid)
|
||||
{
|
||||
struct p9pnode *p9n;
|
||||
struct puffs_node *pn;
|
||||
|
||||
p9n = emalloc(sizeof(struct p9pnode));
|
||||
memset(p9n, 0, sizeof(struct p9pnode));
|
||||
p9n->fid_base = fid;
|
||||
LIST_INIT(&p9n->dir_openlist);
|
||||
|
||||
pn = puffs_pn_new(pu, p9n);
|
||||
if (pn == NULL)
|
||||
abort();
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
struct puffs_node *
|
||||
newp9pnode_va(struct puffs_usermount *pu, const struct vattr *va, p9pfid_t fid)
|
||||
{
|
||||
struct puffs_node *pn;
|
||||
|
||||
pn = makep9pnode(pu, fid);
|
||||
pn->pn_va = *va;
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
struct puffs_node *
|
||||
newp9pnode_qid(struct puffs_usermount *pu, const struct qid9p *qid,
|
||||
p9pfid_t fid)
|
||||
{
|
||||
struct puffs_node *pn;
|
||||
|
||||
pn = makep9pnode(pu, fid);
|
||||
puffs_vattr_null(&pn->pn_va);
|
||||
qid2vattr(&pn->pn_va, qid);
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
/*
|
||||
* search list of fids, or if none is found, walk a fid for a new one
|
||||
* and issue dummy readdirs until we get the result we want
|
||||
*/
|
||||
int
|
||||
getdfwithoffset(struct puffs_usermount *pu, struct p9pnode *p9n, off_t wantoff,
|
||||
struct dirfid **rfid)
|
||||
{
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu);
|
||||
struct puffs9p *p9p = puffs_getspecific(pu);
|
||||
struct puffs_framebuf *pb;
|
||||
struct dirfid *dfp = NULL;
|
||||
p9ptag_t tag = NEXTTAG(p9p);
|
||||
off_t curoff, advance;
|
||||
uint32_t count;
|
||||
int rv;
|
||||
|
||||
LIST_FOREACH(dfp, &p9n->dir_openlist, entries) {
|
||||
if (dfp->seekoff == wantoff) {
|
||||
LIST_REMOVE(dfp, entries);
|
||||
*rfid = dfp;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* didn't get off easy? damn, do manual labour */
|
||||
pb = p9pbuf_makeout();
|
||||
dfp = ecalloc(1, sizeof(struct dirfid));
|
||||
dfp->fid = NEXTFID(p9p);
|
||||
rv = proto_cc_open(pu, p9n->fid_base, dfp->fid, P9PROTO_OMODE_READ);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
for (curoff = 0;;) {
|
||||
advance = wantoff - curoff;
|
||||
|
||||
tag = NEXTTAG(p9p);
|
||||
p9pbuf_put_1(pb, P9PROTO_T_READ);
|
||||
p9pbuf_put_2(pb, tag);
|
||||
p9pbuf_put_4(pb, dfp->fid);
|
||||
p9pbuf_put_8(pb, 0);
|
||||
p9pbuf_put_4(pb, advance);
|
||||
GETRESPONSE(pb);
|
||||
|
||||
if (p9pbuf_get_type(pb) != P9PROTO_R_READ) {
|
||||
rv = EPROTO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check how many bytes we got. If we got the amount we
|
||||
* wanted, we are at the correct position. If we got
|
||||
* zero bytes, either the directory doesn't "support" the
|
||||
* seek offset we want (someone has probably inserted an
|
||||
* entry meantime) or we at the end of directory. Either
|
||||
* way, let the upper layer deal with it.
|
||||
*/
|
||||
p9pbuf_get_4(pb, &count);
|
||||
curoff += count;
|
||||
if (count == advance || count == 0)
|
||||
break;
|
||||
|
||||
p9pbuf_recycleout(pb);
|
||||
}
|
||||
puffs_framebuf_destroy(pb);
|
||||
|
||||
dfp->seekoff = curoff;
|
||||
*rfid = dfp;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
puffs_framebuf_destroy(pb);
|
||||
free(dfp);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
releasedf(struct puffs_usermount *pu, struct dirfid *dfp)
|
||||
{
|
||||
|
||||
proto_cc_clunkfid(pu, dfp->fid, 0);
|
||||
free(dfp);
|
||||
}
|
||||
|
||||
void
|
||||
storedf(struct p9pnode *p9n, struct dirfid *dfp)
|
||||
{
|
||||
|
||||
LIST_INSERT_HEAD(&p9n->dir_openlist, dfp, entries);
|
||||
}
|
||||
|
||||
void
|
||||
nukealldf(struct puffs_usermount *pu, struct p9pnode *p9n)
|
||||
{
|
||||
struct dirfid *dfp;
|
||||
|
||||
while ((dfp = LIST_FIRST(&p9n->dir_openlist)) != NULL) {
|
||||
LIST_REMOVE(dfp, entries);
|
||||
releasedf(pu, dfp);
|
||||
}
|
||||
}
|
||||
9
usr.sbin/puffs/mount_psshfs/Makefile
Normal file
9
usr.sbin/puffs/mount_psshfs/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# $NetBSD: Makefile,v 1.4 2009/04/22 15:23:07 lukem Exp $
|
||||
|
||||
PROG= mount_psshfs
|
||||
SRCS= psshfs.c fs.c node.c psbuf.c subr.c
|
||||
LDADD+= -lpuffs -lutil
|
||||
|
||||
MAN= mount_psshfs.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
279
usr.sbin/puffs/mount_psshfs/fs.c
Normal file
279
usr.sbin/puffs/mount_psshfs/fs.c
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
/* $NetBSD: fs.c,v 1.24 2011/06/22 04:03:23 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: fs.c,v 1.24 2011/06/22 04:03:23 mrg Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <puffs.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "psshfs.h"
|
||||
#include "sftp_proto.h"
|
||||
|
||||
#define DO_IO(fname, a1, a2, a3, a4, rv) \
|
||||
do { \
|
||||
puffs_framebuf_seekset(a2, 0); \
|
||||
*(a4) = 0; \
|
||||
rv = fname(a1, a2, a3, a4); \
|
||||
if (rv) { \
|
||||
return rv ? rv : EPROTO; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define reterr(str, rv) \
|
||||
do { \
|
||||
fprintf str; \
|
||||
return rv; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
/* openssh extensions */
|
||||
static const struct extunit {
|
||||
const char *ext;
|
||||
const char *val;
|
||||
int extflag;
|
||||
} exttable[] = {
|
||||
{
|
||||
"posix-rename@openssh.com",
|
||||
"1",
|
||||
SFTP_EXT_POSIX_RENAME,
|
||||
},{
|
||||
"statvfs@openssh.com",
|
||||
"2",
|
||||
SFTP_EXT_STATVFS,
|
||||
},{
|
||||
"fstatvfs@openssh.com",
|
||||
"2",
|
||||
SFTP_EXT_FSTATVFS,
|
||||
},{
|
||||
NULL,
|
||||
NULL,
|
||||
0
|
||||
}};
|
||||
|
||||
int
|
||||
psshfs_handshake(struct puffs_usermount *pu, int fd)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
struct puffs_framebuf *pb;
|
||||
struct puffs_pathobj *po_root;
|
||||
struct puffs_node *pn_root;
|
||||
struct vattr va, *rva;
|
||||
const struct extunit *extu;
|
||||
char *rootpath;
|
||||
char *ext, *val;
|
||||
uint32_t count;
|
||||
int rv, done;
|
||||
|
||||
pb = psbuf_makeout();
|
||||
psbuf_put_1(pb, SSH_FXP_INIT);
|
||||
psbuf_put_4(pb, SFTP_PROTOVERSION);
|
||||
DO_IO(psbuf_write, pu, pb, fd, &done, rv);
|
||||
|
||||
puffs_framebuf_recycle(pb);
|
||||
DO_IO(psbuf_read, pu, pb, fd, &done, rv);
|
||||
if (psbuf_get_type(pb) != SSH_FXP_VERSION)
|
||||
reterr((stderr, "invalid server response: %d",
|
||||
psbuf_get_type(pb)), EPROTO);
|
||||
pctx->protover = psbuf_get_reqid(pb);
|
||||
|
||||
/*
|
||||
* Check out which extensions are available. Currently
|
||||
* we are only interested in the openssh statvfs extension.
|
||||
*/
|
||||
for (;;) {
|
||||
if (psbuf_get_str(pb, &ext, NULL) != 0)
|
||||
break;
|
||||
if (psbuf_get_str(pb, &val, NULL) != 0)
|
||||
break;
|
||||
|
||||
for (extu = exttable; extu->ext; extu++)
|
||||
if (strcmp(ext, extu->ext) == 0
|
||||
&& strcmp(val, extu->val) == 0)
|
||||
pctx->extensions |= extu->extflag;
|
||||
}
|
||||
|
||||
/* scope out our rootpath */
|
||||
psbuf_recycleout(pb);
|
||||
psbuf_put_1(pb, SSH_FXP_REALPATH);
|
||||
psbuf_put_4(pb, NEXTREQ(pctx));
|
||||
psbuf_put_str(pb, pctx->mountpath);
|
||||
DO_IO(psbuf_write, pu, pb, fd, &done, rv);
|
||||
|
||||
puffs_framebuf_recycle(pb);
|
||||
DO_IO(psbuf_read, pu, pb, fd, &done, rv);
|
||||
if (psbuf_get_type(pb) != SSH_FXP_NAME)
|
||||
reterr((stderr, "invalid server realpath response for \"%s\"",
|
||||
pctx->mountpath), EPROTO);
|
||||
if (psbuf_get_4(pb, &count) == -1)
|
||||
reterr((stderr, "invalid realpath response: count"), EPROTO);
|
||||
if (psbuf_get_str(pb, &rootpath, NULL) == -1)
|
||||
reterr((stderr, "invalid realpath response: rootpath"), EPROTO);
|
||||
|
||||
/* stat the rootdir so that we know it's a dir */
|
||||
psbuf_recycleout(pb);
|
||||
psbuf_req_str(pb, SSH_FXP_LSTAT, NEXTREQ(pctx), rootpath);
|
||||
DO_IO(psbuf_write, pu, pb, fd, &done, rv);
|
||||
|
||||
puffs_framebuf_recycle(pb);
|
||||
DO_IO(psbuf_read, pu, pb, fd, &done, rv);
|
||||
|
||||
rv = psbuf_expect_attrs(pb, &va);
|
||||
if (rv)
|
||||
reterr((stderr, "couldn't stat rootpath"), rv);
|
||||
puffs_framebuf_destroy(pb);
|
||||
|
||||
if (puffs_mode2vt(va.va_mode) != VDIR)
|
||||
reterr((stderr, "remote path (%s) not a directory", rootpath),
|
||||
ENOTDIR);
|
||||
|
||||
pn_root = puffs_getroot(pu);
|
||||
rva = &pn_root->pn_va;
|
||||
puffs_setvattr(rva, &va);
|
||||
|
||||
po_root = puffs_getrootpathobj(pu);
|
||||
if (po_root == NULL)
|
||||
err(1, "getrootpathobj");
|
||||
po_root->po_path = rootpath;
|
||||
po_root->po_len = strlen(rootpath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp)
|
||||
{
|
||||
PSSHFSAUTOVAR(pu);
|
||||
uint64_t tmpval;
|
||||
uint8_t type;
|
||||
|
||||
memset(sbp, 0, sizeof(*sbp));
|
||||
sbp->f_bsize = sbp->f_frsize = sbp->f_iosize = 512;
|
||||
|
||||
if ((pctx->extensions & SFTP_EXT_STATVFS) == 0)
|
||||
goto out;
|
||||
|
||||
psbuf_req_str(pb, SSH_FXP_EXTENDED, reqid, "statvfs@openssh.com");
|
||||
psbuf_put_str(pb, pctx->mountpath);
|
||||
GETRESPONSE(pb, pctx->sshfd);
|
||||
|
||||
type = psbuf_get_type(pb);
|
||||
if (type != SSH_FXP_EXTENDED_REPLY) {
|
||||
/* use the default */
|
||||
goto out;
|
||||
}
|
||||
|
||||
psbuf_get_8(pb, &tmpval);
|
||||
sbp->f_bsize = tmpval;
|
||||
psbuf_get_8(pb, &tmpval);
|
||||
sbp->f_frsize = tmpval;
|
||||
psbuf_get_8(pb, &sbp->f_blocks);
|
||||
psbuf_get_8(pb, &sbp->f_bfree);
|
||||
psbuf_get_8(pb, &sbp->f_bavail);
|
||||
psbuf_get_8(pb, &sbp->f_files);
|
||||
psbuf_get_8(pb, &sbp->f_ffree);
|
||||
psbuf_get_8(pb, &sbp->f_favail);
|
||||
|
||||
psbuf_get_8(pb, &tmpval); /* fsid */
|
||||
psbuf_get_8(pb, &tmpval); /* flag */
|
||||
psbuf_get_8(pb, &tmpval);
|
||||
sbp->f_namemax = tmpval;
|
||||
|
||||
sbp->f_bresvd = sbp->f_bfree - sbp->f_bavail;
|
||||
sbp->f_fresvd = sbp->f_ffree - sbp->f_favail;
|
||||
|
||||
out:
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_fs_unmount(struct puffs_usermount *pu, int flags)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
|
||||
kill(pctx->sshpid, SIGTERM);
|
||||
close(pctx->sshfd);
|
||||
if (pctx->numconnections == 2) {
|
||||
kill(pctx->sshpid_data, SIGTERM);
|
||||
close(pctx->sshfd_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie,
|
||||
void *fid, size_t *fidsize)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
struct puffs_node *pn = cookie;
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
struct psshfs_fid *pf = fid;
|
||||
|
||||
pf->mounttime = pctx->mounttime;
|
||||
pf->node = pn;
|
||||
|
||||
psn->stat |= PSN_HASFH;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
|
||||
struct puffs_newinfo *pni)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
struct psshfs_fid *pf = fid;
|
||||
struct puffs_node *pn = pf->node;
|
||||
struct psshfs_node *psn;
|
||||
int rv;
|
||||
|
||||
if (pf->mounttime != pctx->mounttime)
|
||||
return EINVAL;
|
||||
if (pn == 0)
|
||||
return EINVAL;
|
||||
psn = pn->pn_data;
|
||||
if ((psn->stat & PSN_HASFH) == 0)
|
||||
return EINVAL;
|
||||
|
||||
/* update node attributes */
|
||||
rv = getnodeattr(pu, pn, NULL);
|
||||
if (rv)
|
||||
return EINVAL;
|
||||
|
||||
puffs_newinfo_setcookie(pni, pn);
|
||||
puffs_newinfo_setvtype(pni, pn->pn_va.va_type);
|
||||
puffs_newinfo_setsize(pni, pn->pn_va.va_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
205
usr.sbin/puffs/mount_psshfs/mount_psshfs.8
Normal file
205
usr.sbin/puffs/mount_psshfs/mount_psshfs.8
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
.\" $NetBSD: mount_psshfs.8,v 1.27 2014/06/25 23:22:18 szptvlfn Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2007-2009 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd January 7, 2010
|
||||
.Dt MOUNT_PSSHFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mount_psshfs
|
||||
.Nd sshfs implementation for puffs
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Ar options
|
||||
.Ar user@host[:path]
|
||||
.Ar mount_point
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount a file system using the ssh sftp
|
||||
subprotocol, making a remote directory hierarchy appear in the
|
||||
local directory tree.
|
||||
This functionality is commonly known as
|
||||
.Em sshfs .
|
||||
.Pp
|
||||
The mandatory parameters are the target host name and local mount
|
||||
point.
|
||||
The target host parameter can optionally contain a username whose
|
||||
credentials will be used by the remote sshd, and a relative or
|
||||
absolute path for the remote mount point's root.
|
||||
If no user is given, the credentials of the user issuing the mount
|
||||
command are used.
|
||||
If no path is given, the user's home directory on the remote machine
|
||||
will be used.
|
||||
.Pp
|
||||
The following command line options are available:
|
||||
.Pp
|
||||
.Bl -tag -width xxx
|
||||
.It Fl c Ar nconnect
|
||||
Opens
|
||||
.Ar nconnect
|
||||
connections to the server.
|
||||
Currently, the value has to be 1 or 2.
|
||||
If 2 is specified, a second connection is opened for the reading
|
||||
and writing of data, while directory operations are performed on
|
||||
their own connection.
|
||||
This can greatly increase directory operation performance (ls,
|
||||
mkdir, etc.) if
|
||||
.Nm
|
||||
completely saturates the available bandwidth by doing bulk data copying.
|
||||
The default is 1.
|
||||
.It Fl e
|
||||
Makes the mounted file system NFS exportable.
|
||||
If this option is used, it is very important to understand that
|
||||
.Nm
|
||||
can not provide complete support for NFS due to the limitations in
|
||||
the backend.
|
||||
Files are valid only for the time that
|
||||
.Nm
|
||||
is running and in the event of e.g. a server crash, all client retries
|
||||
to access files will fail.
|
||||
.It Fl F Ar configfile
|
||||
Pass a configuration file to
|
||||
.Xr ssh 1 .
|
||||
This will make it ignore the system-wide
|
||||
.Pa /etc/ssh/ssh_config
|
||||
configuration file and use
|
||||
.Pa configfile
|
||||
instead of
|
||||
.Pa ~/.ssh/config .
|
||||
.It Fl g Ar manglegid
|
||||
Converts remote
|
||||
.Ar manglegid
|
||||
to the effective gid of the file server and vice versa.
|
||||
See
|
||||
.Fl u .
|
||||
.It Fl o Ar [no]option
|
||||
This flag can be used to give standard mount options and options
|
||||
to puffs.
|
||||
.It Fl O Ar sshopt=value
|
||||
Pass an option to
|
||||
.Xr ssh 1 ,
|
||||
for example
|
||||
.Fl O Ar Port=22 .
|
||||
For a list of valid options, see
|
||||
.Xr ssh_config 5 .
|
||||
.It Fl p
|
||||
Preserve connection.
|
||||
This option makes
|
||||
.Nm
|
||||
to try to reconnect to the server if the connection fails.
|
||||
The option is very experimental and does not preserve open files
|
||||
or retry current requests and should generally only be used if the
|
||||
trade-offs are well understood.
|
||||
.It Fl r Ar max_reads
|
||||
Limits maximum outstanding read requests for each node to
|
||||
.Ar max_reads .
|
||||
This can be used to improve interactive performance on low-bandwidth links
|
||||
when also performing bulk data reads.
|
||||
.It Fl s
|
||||
This flag can be used to make the program stay on top.
|
||||
The default is to detach from the terminal and run in the background.
|
||||
.It Fl t Ar timeout
|
||||
By default
|
||||
.Nm
|
||||
caches directory contents and node attributes for 30 seconds before
|
||||
re-fetching from the server to check if anything has changed on
|
||||
the server.
|
||||
This option is used to adjust the timeout period to
|
||||
.Ar timeout
|
||||
seconds.
|
||||
A value of 0 means the cache is never valid; \-1 means it is
|
||||
valid indefinitely.
|
||||
It is possible to force a re-read regardless of timeout status by sending
|
||||
.Dv SIGHUP
|
||||
to the
|
||||
.Nm
|
||||
process.
|
||||
.Pp
|
||||
Note: the file system will still free nodes when requested by the
|
||||
kernel and will lose all cached information in doing so.
|
||||
How frequently this happens depends on system activity and the total
|
||||
number of available vnodes in the system (kern.maxvnodes).
|
||||
.It Fl u Ar mangleuid
|
||||
Converts remote
|
||||
.Ar mangleuid
|
||||
to the effective uid of the file server and vice versa.
|
||||
This is a simple special case of the functionality of
|
||||
.Xr mount_umap 8 .
|
||||
For example: you mount remote me@darkmoon as the local user "me".
|
||||
If the uid of "me" on the local system is 101 and on
|
||||
darkmoon it is 202, you would use
|
||||
.Fl u
|
||||
.Ar 202
|
||||
to see files owned by 202 on darkmoon as owned by 101 when browsing the
|
||||
mount point.
|
||||
Apart from the cosmetic effect, this makes things like
|
||||
"chown me file" work.
|
||||
See
|
||||
.Fl g .
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
The following example illustrates how to mount the directory
|
||||
.Em /usr
|
||||
on server
|
||||
.Em bigiron
|
||||
as user
|
||||
.Em abc
|
||||
on local directory
|
||||
.Em /mnt
|
||||
with ssh transport compression enabled:
|
||||
.Bd -literal -offset indent
|
||||
mount_psshfs -O Compression=yes abc@bigiron:/usr /mnt
|
||||
.Ed
|
||||
.Pp
|
||||
It is possible to use
|
||||
.Xr fstab 5
|
||||
for psshfs mounts, with SSH public key authentication:
|
||||
.Pp
|
||||
.Dl "abc@bigiron:/usr /mnt psshfs rw,noauto,-O=BatchMode=yes,-O=IdentityFile=/root/.ssh/id_rsa,-t=-1"
|
||||
.Sh SEE ALSO
|
||||
.Xr sftp 1 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr puffs 4 ,
|
||||
.Xr fstab 5 ,
|
||||
.Xr ssh_config 5 ,
|
||||
.Xr mount 8 ,
|
||||
.Xr sshd 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
It was inspired by FUSE sshfs.
|
||||
.Sh CAVEATS
|
||||
Permissions are not handled.
|
||||
Do not expect the file system to behave except for a single user.
|
||||
.Pp
|
||||
Depending on if the server supports the
|
||||
.Xr sftp 1
|
||||
statvfs protocol extension,
|
||||
free disk space may be displayed for the mount by
|
||||
.Xr df 1 .
|
||||
This information reflects the status at the server's mountpoint
|
||||
and may differ for subdirectories under the mount root.
|
||||
949
usr.sbin/puffs/mount_psshfs/node.c
Normal file
949
usr.sbin/puffs/mount_psshfs/node.c
Normal file
|
|
@ -0,0 +1,949 @@
|
|||
/* $NetBSD: node.c,v 1.64 2012/01/20 22:07:58 jakllsch Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: node.c,v 1.64 2012/01/20 22:07:58 jakllsch Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "psshfs.h"
|
||||
#include "sftp_proto.h"
|
||||
|
||||
int
|
||||
psshfs_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
struct puffs_newinfo *pni, const struct puffs_cn *pcn)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
struct puffs_node *pn_dir = opc;
|
||||
struct psshfs_node *psn, *psn_dir = pn_dir->pn_data;
|
||||
struct puffs_node *pn;
|
||||
struct psshfs_dir *pd;
|
||||
struct vattr va;
|
||||
int rv;
|
||||
|
||||
if (PCNISDOTDOT(pcn)) {
|
||||
psn = psn_dir->parent->pn_data;
|
||||
psn->stat &= ~PSN_RECLAIMED;
|
||||
|
||||
puffs_newinfo_setcookie(pni, psn_dir->parent);
|
||||
puffs_newinfo_setvtype(pni, VDIR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = sftp_readdir(pu, pctx, pn_dir);
|
||||
if (rv) {
|
||||
if (rv != EPERM)
|
||||
return rv;
|
||||
|
||||
/*
|
||||
* Can't read the directory. We still might be
|
||||
* able to find the node with getattr in -r+x dirs
|
||||
*/
|
||||
rv = getpathattr(pu, PCNPATH(pcn), &va);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
/* guess */
|
||||
if (va.va_type == VDIR)
|
||||
va.va_nlink = 2;
|
||||
else
|
||||
va.va_nlink = 1;
|
||||
|
||||
pn = allocnode(pu, pn_dir, pcn->pcn_name, &va);
|
||||
psn = pn->pn_data;
|
||||
psn->attrread = time(NULL);
|
||||
} else {
|
||||
pd = lookup(psn_dir->dir, psn_dir->dentnext, pcn->pcn_name);
|
||||
if (!pd) {
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (pd->entry)
|
||||
pn = pd->entry;
|
||||
else
|
||||
pd->entry = pn = makenode(pu, pn_dir, pd, &pd->va);
|
||||
|
||||
/*
|
||||
* sure sure we have fresh attributes. most likely we will
|
||||
* have them cached. we might not if we go through:
|
||||
* create - reclaim - lookup (this).
|
||||
*/
|
||||
rv = getnodeattr(pu, pn, PCNPATH(pcn));
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
psn = pn->pn_data;
|
||||
}
|
||||
|
||||
psn->stat &= ~PSN_RECLAIMED;
|
||||
|
||||
puffs_newinfo_setcookie(pni, pn);
|
||||
puffs_newinfo_setvtype(pni, pn->pn_va.va_type);
|
||||
puffs_newinfo_setsize(pni, pn->pn_va.va_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
struct vattr *vap, const struct puffs_cred *pcr)
|
||||
{
|
||||
struct puffs_node *pn = opc;
|
||||
int rv;
|
||||
|
||||
rv = getnodeattr(pu, pn, NULL);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
memcpy(vap, &pn->pn_va, sizeof(struct vattr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
const struct vattr *va, const struct puffs_cred *pcr)
|
||||
{
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu);
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
uint32_t reqid;
|
||||
struct puffs_framebuf *pb;
|
||||
struct vattr kludgeva;
|
||||
struct puffs_node *pn = opc;
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
int rv;
|
||||
|
||||
/*
|
||||
* If we cached the remote attributes recently enough, and this
|
||||
* setattr operation would change nothing that sftp actually
|
||||
* records, then we can skip the sftp request. So first check
|
||||
* whether we have the attributes cached, and then compare
|
||||
* every field that we might send to the sftp server.
|
||||
*/
|
||||
|
||||
if (!psn->attrread || REFRESHTIMEOUT(pctx, time(NULL)-psn->attrread))
|
||||
goto setattr;
|
||||
|
||||
#define CHECK(FIELD, TYPE) do { \
|
||||
if ((va->FIELD != (TYPE)PUFFS_VNOVAL) && \
|
||||
(va->FIELD != pn->pn_va.FIELD)) \
|
||||
goto setattr; \
|
||||
} while (0)
|
||||
|
||||
#define CHECKID(FIELD, TYPE, DOMANGLE, MINE, MANGLED) do { \
|
||||
if ((va->FIELD != (TYPE)PUFFS_VNOVAL) && \
|
||||
(pn->pn_va.FIELD != \
|
||||
((pctx->DOMANGLE && (va->FIELD == pctx->MINE)) \
|
||||
? pctx->MANGLED \
|
||||
: va->FIELD))) \
|
||||
goto setattr; \
|
||||
} while (0)
|
||||
|
||||
CHECK(va_size, uint64_t);
|
||||
CHECKID(va_uid, uid_t, domangleuid, myuid, mangleuid);
|
||||
CHECKID(va_gid, gid_t, domanglegid, mygid, manglegid);
|
||||
CHECK(va_mode, mode_t);
|
||||
CHECK(va_atime.tv_sec, time_t);
|
||||
CHECK(va_mtime.tv_sec, time_t);
|
||||
|
||||
/* Nothing to change. */
|
||||
return 0;
|
||||
|
||||
#undef CHECK
|
||||
#undef CHECKID
|
||||
|
||||
setattr:
|
||||
reqid = NEXTREQ(pctx);
|
||||
pb = psbuf_makeout();
|
||||
|
||||
psbuf_req_str(pb, SSH_FXP_SETSTAT, reqid, PNPATH(pn));
|
||||
|
||||
memcpy(&kludgeva, va, sizeof(struct vattr));
|
||||
|
||||
/* XXX: kludge due to openssh server implementation */
|
||||
if (va->va_atime.tv_sec != PUFFS_VNOVAL
|
||||
&& va->va_mtime.tv_sec == PUFFS_VNOVAL) {
|
||||
if (pn->pn_va.va_mtime.tv_sec != PUFFS_VNOVAL)
|
||||
kludgeva.va_mtime.tv_sec = pn->pn_va.va_mtime.tv_sec;
|
||||
else
|
||||
kludgeva.va_mtime.tv_sec = va->va_atime.tv_sec;
|
||||
}
|
||||
if (va->va_mtime.tv_sec != PUFFS_VNOVAL
|
||||
&& va->va_atime.tv_sec == PUFFS_VNOVAL) {
|
||||
if (pn->pn_va.va_atime.tv_sec != PUFFS_VNOVAL)
|
||||
kludgeva.va_atime.tv_sec = pn->pn_va.va_atime.tv_sec;
|
||||
else
|
||||
kludgeva.va_atime.tv_sec = va->va_mtime.tv_sec;
|
||||
}
|
||||
|
||||
psbuf_put_vattr(pb, &kludgeva, pctx);
|
||||
GETRESPONSE(pb, pctx->sshfd);
|
||||
|
||||
rv = psbuf_expect_status(pb);
|
||||
if (rv == 0) {
|
||||
puffs_setvattr(&pn->pn_va, &kludgeva);
|
||||
psn->attrread = time(NULL);
|
||||
}
|
||||
|
||||
out:
|
||||
puffs_framebuf_destroy(pb);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_create(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
struct puffs_newinfo *pni, const struct puffs_cn *pcn,
|
||||
const struct vattr *va)
|
||||
{
|
||||
PSSHFSAUTOVAR(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct puffs_node *pn_new;
|
||||
char *fhand = NULL;
|
||||
uint32_t fhandlen;
|
||||
|
||||
/* Create node on server first */
|
||||
psbuf_req_str(pb, SSH_FXP_OPEN, reqid, PCNPATH(pcn));
|
||||
psbuf_put_4(pb, SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC);
|
||||
psbuf_put_vattr(pb, va, pctx);
|
||||
GETRESPONSE(pb, pctx->sshfd);
|
||||
rv = psbuf_expect_handle(pb, &fhand, &fhandlen);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Do *not* create the local node before getting a response
|
||||
* from the server. Otherwise we might screw up consistency,
|
||||
* namely that the node can be looked up before create has
|
||||
* returned (mind you, the kernel will unlock the directory
|
||||
* before the create call from userspace returns).
|
||||
*/
|
||||
pn_new = allocnode(pu, pn, pcn->pcn_name, va);
|
||||
if (!pn_new) {
|
||||
struct puffs_framebuf *pb2 = psbuf_makeout();
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_req_str(pb2, SSH_FXP_REMOVE, reqid, PCNPATH(pcn));
|
||||
JUSTSEND(pb2, pctx->sshfd);
|
||||
rv = ENOMEM;
|
||||
}
|
||||
|
||||
if (pn_new)
|
||||
puffs_newinfo_setcookie(pni, pn_new);
|
||||
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_recycleout(pb);
|
||||
psbuf_req_data(pb, SSH_FXP_CLOSE, reqid, fhand, fhandlen);
|
||||
JUSTSEND(pb, pctx->sshfd);
|
||||
free(fhand);
|
||||
return rv;
|
||||
|
||||
out:
|
||||
free(fhand);
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a file handle. This is used for read and write. We do not
|
||||
* wait here for the success or failure of this operation. This is
|
||||
* because otherwise opening and closing file handles would block
|
||||
* reading potentially cached information. Rather, we defer the wait
|
||||
* to read/write and therefore allow cached access without a wait.
|
||||
*
|
||||
* If we have not yet succesfully opened a type of handle, we do wait
|
||||
* here. Also, if a lazy open fails, we revert back to the same
|
||||
* state of waiting.
|
||||
*/
|
||||
int
|
||||
psshfs_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
|
||||
const struct puffs_cred *pcr)
|
||||
{
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu);
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
struct puffs_framebuf *pb, *pb2;
|
||||
struct vattr va;
|
||||
struct puffs_node *pn = opc;
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
uint32_t reqid;
|
||||
int didread, didwrite;
|
||||
int rv = 0;
|
||||
|
||||
if (pn->pn_va.va_type == VDIR)
|
||||
return 0;
|
||||
|
||||
puffs_setback(pcc, PUFFS_SETBACK_INACT_N1);
|
||||
puffs_vattr_null(&va);
|
||||
didread = didwrite = 0;
|
||||
if (mode & FREAD && psn->fhand_r == NULL && psn->lazyopen_r == NULL) {
|
||||
pb = psbuf_makeout();
|
||||
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_req_str(pb, SSH_FXP_OPEN, reqid, PNPATH(pn));
|
||||
psbuf_put_4(pb, SSH_FXF_READ);
|
||||
psbuf_put_vattr(pb, &va, pctx);
|
||||
|
||||
if (puffs_framev_enqueue_cb(pu, pctx->sshfd_data, pb,
|
||||
lazyopen_rresp, psn, 0) == -1) {
|
||||
rv = errno;
|
||||
puffs_framebuf_destroy(pb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
psn->lazyopen_r = pb;
|
||||
didread = 1;
|
||||
}
|
||||
if (mode & FWRITE && psn->fhand_w == NULL && psn->lazyopen_w == NULL) {
|
||||
pb2 = psbuf_makeout();
|
||||
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_req_str(pb2, SSH_FXP_OPEN, reqid, PNPATH(pn));
|
||||
psbuf_put_4(pb2, SSH_FXF_WRITE);
|
||||
psbuf_put_vattr(pb2, &va, pctx);
|
||||
|
||||
if (puffs_framev_enqueue_cb(pu, pctx->sshfd_data, pb2,
|
||||
lazyopen_wresp, psn, 0) == -1) {
|
||||
rv = errno;
|
||||
puffs_framebuf_destroy(pb2);
|
||||
goto out;
|
||||
}
|
||||
|
||||
psn->lazyopen_w = pb2;
|
||||
didwrite = 1;
|
||||
}
|
||||
psn->stat &= ~PSN_HANDLECLOSE;
|
||||
|
||||
out:
|
||||
/* wait? */
|
||||
if (didread && (psn->stat & PSN_DOLAZY_R) == 0) {
|
||||
assert(psn->lazyopen_r);
|
||||
|
||||
rv = puffs_framev_framebuf_ccpromote(psn->lazyopen_r, pcc);
|
||||
lazyopen_rresp(pu, psn->lazyopen_r, psn, rv);
|
||||
if (psn->fhand_r) {
|
||||
psn->stat |= PSN_DOLAZY_R;
|
||||
} else {
|
||||
if (psn->lazyopen_err_r)
|
||||
return psn->lazyopen_err_r;
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* wait? */
|
||||
if (didwrite && (psn->stat & PSN_DOLAZY_W) == 0) {
|
||||
assert(psn->lazyopen_w);
|
||||
|
||||
rv = puffs_framev_framebuf_ccpromote(psn->lazyopen_w, pcc);
|
||||
lazyopen_wresp(pu, psn->lazyopen_w, psn, rv);
|
||||
if (psn->fhand_w) {
|
||||
psn->stat |= PSN_DOLAZY_W;
|
||||
} else {
|
||||
if (psn->lazyopen_err_w)
|
||||
return psn->lazyopen_err_w;
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_inactive(struct puffs_usermount *pu, puffs_cookie_t opc)
|
||||
{
|
||||
struct puffs_node *pn = opc;
|
||||
|
||||
closehandles(pu, pn->pn_data, HANDLE_READ | HANDLE_WRITE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_readdir(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
struct dirent *dent, off_t *readoff, size_t *reslen,
|
||||
const struct puffs_cred *pcr, int *eofflag,
|
||||
off_t *cookies, size_t *ncookies)
|
||||
{
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu);
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
struct psshfs_dir *pd;
|
||||
size_t i;
|
||||
int rv, set_readdir;
|
||||
|
||||
restart:
|
||||
if (psn->stat & PSN_READDIR) {
|
||||
struct psshfs_wait pw;
|
||||
|
||||
set_readdir = 0;
|
||||
pw.pw_cc = pcc;
|
||||
pw.pw_type = PWTYPE_READDIR;
|
||||
TAILQ_INSERT_TAIL(&psn->pw, &pw, pw_entries);
|
||||
puffs_cc_yield(pcc);
|
||||
goto restart;
|
||||
} else {
|
||||
psn->stat |= PSN_READDIR;
|
||||
set_readdir = 1;
|
||||
}
|
||||
|
||||
*ncookies = 0;
|
||||
rv = sftp_readdir(pu, pctx, pn);
|
||||
if (rv) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* find next dirent */
|
||||
for (i = *readoff;;i++) {
|
||||
if (i >= psn->dentnext)
|
||||
goto out;
|
||||
pd = &psn->dir[i];
|
||||
if (pd->valid)
|
||||
break;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
*readoff = i;
|
||||
if (!puffs_nextdent(&dent, pd->entryname,
|
||||
pd->va.va_fileid, puffs_vtype2dt(pd->va.va_type), reslen)) {
|
||||
rv = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* find next entry, store possible nfs key */
|
||||
do {
|
||||
if (++i >= psn->dentnext)
|
||||
goto out;
|
||||
pd = &psn->dir[i];
|
||||
} while (pd->valid == 0);
|
||||
PUFFS_STORE_DCOOKIE(cookies, ncookies, (off_t)i);
|
||||
}
|
||||
|
||||
out:
|
||||
if (rv == 0) {
|
||||
if (i >= psn->dentnext)
|
||||
*eofflag = 1;
|
||||
|
||||
*readoff = i;
|
||||
}
|
||||
|
||||
if (set_readdir) {
|
||||
struct psshfs_wait *pw;
|
||||
|
||||
/* all will likely run to completion because of cache */
|
||||
TAILQ_FOREACH(pw, &psn->pw, pw_entries) {
|
||||
assert(pw->pw_type == PWTYPE_READDIR);
|
||||
puffs_cc_schedule(pw->pw_cc);
|
||||
TAILQ_REMOVE(&psn->pw, pw, pw_entries);
|
||||
}
|
||||
|
||||
psn->stat &= ~PSN_READDIR;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_read(struct puffs_usermount *pu, puffs_cookie_t opc, uint8_t *buf,
|
||||
off_t offset, size_t *resid, const struct puffs_cred *pcr,
|
||||
int ioflag)
|
||||
{
|
||||
PSSHFSAUTOVAR(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
struct psshfs_wait *pwp;
|
||||
uint32_t readlen;
|
||||
|
||||
if (pn->pn_va.va_type == VDIR) {
|
||||
rv = EISDIR;
|
||||
goto farout;
|
||||
}
|
||||
|
||||
/* check that a lazyopen didn't fail */
|
||||
if (!psn->fhand_r && !psn->lazyopen_r) {
|
||||
rv = psn->lazyopen_err_r;
|
||||
goto farout;
|
||||
}
|
||||
|
||||
/* if someone is already waiting for the lazyopen, "just" wait */
|
||||
if (psn->stat & PSN_LAZYWAIT_R) {
|
||||
struct psshfs_wait pw;
|
||||
|
||||
assert(psn->lazyopen_r);
|
||||
|
||||
pw.pw_cc = pcc;
|
||||
pw.pw_type = PWTYPE_READ1;
|
||||
TAILQ_INSERT_TAIL(&psn->pw, &pw, pw_entries);
|
||||
puffs_cc_yield(pcc);
|
||||
}
|
||||
|
||||
/* if lazyopening, wait for the result */
|
||||
if (psn->lazyopen_r) {
|
||||
psn->stat |= PSN_LAZYWAIT_R;
|
||||
rv = puffs_framev_framebuf_ccpromote(psn->lazyopen_r, pcc);
|
||||
lazyopen_rresp(pu, psn->lazyopen_r, psn, rv);
|
||||
|
||||
/* schedule extra waiters */
|
||||
TAILQ_FOREACH(pwp, &psn->pw, pw_entries)
|
||||
if (pwp->pw_type == PWTYPE_READ1) {
|
||||
puffs_cc_schedule(pwp->pw_cc);
|
||||
TAILQ_REMOVE(&psn->pw, pwp, pw_entries);
|
||||
}
|
||||
psn->stat &= ~PSN_LAZYWAIT_R;
|
||||
|
||||
if ((rv = psn->lazyopen_err_r) != 0)
|
||||
goto farout;
|
||||
}
|
||||
|
||||
/* if there is still no handle, just refuse to live with this */
|
||||
if (!psn->fhand_r) {
|
||||
rv = EINVAL;
|
||||
goto farout;
|
||||
}
|
||||
|
||||
again:
|
||||
readlen = *resid;
|
||||
psbuf_req_data(pb, SSH_FXP_READ, reqid, psn->fhand_r, psn->fhand_r_len);
|
||||
psbuf_put_8(pb, offset);
|
||||
psbuf_put_4(pb, readlen);
|
||||
|
||||
/*
|
||||
* Do this *after* accessing the file, the handle might not
|
||||
* exist after blocking.
|
||||
*/
|
||||
if (max_reads && ++psn->readcount > max_reads) {
|
||||
struct psshfs_wait pw;
|
||||
|
||||
pw.pw_cc = pcc;
|
||||
pw.pw_type = PWTYPE_READ2;
|
||||
TAILQ_INSERT_TAIL(&psn->pw, &pw, pw_entries);
|
||||
puffs_cc_yield(pcc);
|
||||
}
|
||||
|
||||
GETRESPONSE(pb, pctx->sshfd_data);
|
||||
|
||||
rv = psbuf_do_data(pb, buf, &readlen);
|
||||
if (rv == 0) {
|
||||
*resid -= readlen;
|
||||
buf += readlen;
|
||||
offset += readlen;
|
||||
}
|
||||
|
||||
out:
|
||||
if (max_reads && --psn->readcount >= max_reads) {
|
||||
TAILQ_FOREACH(pwp, &psn->pw, pw_entries)
|
||||
if (pwp->pw_type == PWTYPE_READ2)
|
||||
break;
|
||||
assert(pwp != NULL);
|
||||
puffs_cc_schedule(pwp->pw_cc);
|
||||
TAILQ_REMOVE(&psn->pw, pwp, pw_entries);
|
||||
}
|
||||
|
||||
if (rv == 0 && *resid > 0) {
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_recycleout(pb);
|
||||
goto again;
|
||||
}
|
||||
|
||||
farout:
|
||||
/* check if we need a lazyclose */
|
||||
if (psn->stat & PSN_HANDLECLOSE && psn->fhand_r) {
|
||||
TAILQ_FOREACH(pwp, &psn->pw, pw_entries)
|
||||
if (pwp->pw_type == PWTYPE_READ1)
|
||||
break;
|
||||
if (pwp == NULL)
|
||||
closehandles(pu, psn, HANDLE_READ);
|
||||
}
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
/* XXX: we should getattr for size */
|
||||
int
|
||||
psshfs_node_write(struct puffs_usermount *pu, puffs_cookie_t opc, uint8_t *buf,
|
||||
off_t offset, size_t *resid, const struct puffs_cred *cred,
|
||||
int ioflag)
|
||||
{
|
||||
PSSHFSAUTOVAR(pu);
|
||||
struct psshfs_wait *pwp;
|
||||
struct puffs_node *pn = opc;
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
uint32_t writelen;
|
||||
|
||||
if (pn->pn_va.va_type == VDIR) {
|
||||
rv = EISDIR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check that a lazyopen didn't fail */
|
||||
if (!psn->fhand_w && !psn->lazyopen_w) {
|
||||
rv = psn->lazyopen_err_w;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (psn->stat & PSN_LAZYWAIT_W) {
|
||||
struct psshfs_wait pw;
|
||||
|
||||
assert(psn->lazyopen_w);
|
||||
|
||||
pw.pw_cc = pcc;
|
||||
pw.pw_type = PWTYPE_WRITE;
|
||||
TAILQ_INSERT_TAIL(&psn->pw, &pw, pw_entries);
|
||||
puffs_cc_yield(pcc);
|
||||
}
|
||||
|
||||
/*
|
||||
* If lazyopening, wait for the result.
|
||||
* There can still be more than oen writer at a time in case
|
||||
* the kernel issues write FAFs.
|
||||
*/
|
||||
if (psn->lazyopen_w) {
|
||||
psn->stat |= PSN_LAZYWAIT_W;
|
||||
rv = puffs_framev_framebuf_ccpromote(psn->lazyopen_w, pcc);
|
||||
lazyopen_wresp(pu, psn->lazyopen_w, psn, rv);
|
||||
|
||||
/* schedule extra waiters */
|
||||
TAILQ_FOREACH(pwp, &psn->pw, pw_entries)
|
||||
if (pwp->pw_type == PWTYPE_WRITE) {
|
||||
puffs_cc_schedule(pwp->pw_cc);
|
||||
TAILQ_REMOVE(&psn->pw, pwp, pw_entries);
|
||||
}
|
||||
psn->stat &= ~PSN_LAZYWAIT_W;
|
||||
|
||||
if ((rv = psn->lazyopen_err_w) != 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!psn->fhand_w) {
|
||||
abort();
|
||||
rv = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
writelen = *resid;
|
||||
psbuf_req_data(pb, SSH_FXP_WRITE, reqid, psn->fhand_w,psn->fhand_w_len);
|
||||
psbuf_put_8(pb, offset);
|
||||
psbuf_put_data(pb, buf, writelen);
|
||||
GETRESPONSE(pb, pctx->sshfd_data);
|
||||
|
||||
rv = psbuf_expect_status(pb);
|
||||
if (rv == 0)
|
||||
*resid = 0;
|
||||
|
||||
if (pn->pn_va.va_size < (uint64_t)offset + writelen)
|
||||
pn->pn_va.va_size = offset + writelen;
|
||||
|
||||
out:
|
||||
/* check if we need a lazyclose */
|
||||
if (psn->stat & PSN_HANDLECLOSE && psn->fhand_w) {
|
||||
TAILQ_FOREACH(pwp, &psn->pw, pw_entries)
|
||||
if (pwp->pw_type == PWTYPE_WRITE)
|
||||
break;
|
||||
if (pwp == NULL)
|
||||
closehandles(pu, psn, HANDLE_WRITE);
|
||||
}
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_readlink(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
const struct puffs_cred *cred, char *linkvalue, size_t *linklen)
|
||||
{
|
||||
PSSHFSAUTOVAR(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
uint32_t count;
|
||||
|
||||
if (pctx->protover < 3) {
|
||||
rv = EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* check if we can use a cached version
|
||||
*
|
||||
* XXX: we might end up reading the same link multiple times
|
||||
* from the server if we get many requests at once, but that's
|
||||
* quite harmless as this routine is reentrant.
|
||||
*/
|
||||
if (psn->symlink && !REFRESHTIMEOUT(pctx, time(NULL) - psn->slread))
|
||||
goto copy;
|
||||
|
||||
if (psn->symlink) {
|
||||
free(psn->symlink);
|
||||
psn->symlink = NULL;
|
||||
psn->slread = 0;
|
||||
}
|
||||
|
||||
psbuf_req_str(pb, SSH_FXP_READLINK, reqid, PNPATH(pn));
|
||||
GETRESPONSE(pb, pctx->sshfd);
|
||||
|
||||
rv = psbuf_expect_name(pb, &count);
|
||||
if (rv)
|
||||
goto out;
|
||||
if (count != 1) {
|
||||
rv = EPROTO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = psbuf_get_str(pb, &psn->symlink, NULL);
|
||||
if (rv)
|
||||
goto out;
|
||||
psn->slread = time(NULL);
|
||||
|
||||
copy:
|
||||
*linklen = strlen(psn->symlink);
|
||||
(void) memcpy(linkvalue, psn->symlink, *linklen);
|
||||
|
||||
out:
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
static int
|
||||
doremove(struct puffs_usermount *pu, struct puffs_node *pn_dir,
|
||||
struct puffs_node *pn, const char *name)
|
||||
{
|
||||
PSSHFSAUTOVAR(pu);
|
||||
int op;
|
||||
|
||||
if (pn->pn_va.va_type == VDIR)
|
||||
op = SSH_FXP_RMDIR;
|
||||
else
|
||||
op = SSH_FXP_REMOVE;
|
||||
|
||||
psbuf_req_str(pb, op, reqid, PNPATH(pn));
|
||||
GETRESPONSE(pb, pctx->sshfd);
|
||||
|
||||
rv = psbuf_expect_status(pb);
|
||||
if (rv == 0)
|
||||
nukenode(pn, name, 0);
|
||||
|
||||
out:
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
puffs_cookie_t targ, const struct puffs_cn *pcn)
|
||||
{
|
||||
struct puffs_node *pn_targ = targ;
|
||||
int rv;
|
||||
|
||||
assert(pn_targ->pn_va.va_type != VDIR);
|
||||
|
||||
rv = doremove(pu, opc, targ, pcn->pcn_name);
|
||||
if (rv == 0)
|
||||
puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N2);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_rmdir(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
puffs_cookie_t targ, const struct puffs_cn *pcn)
|
||||
{
|
||||
struct puffs_node *pn_targ = targ;
|
||||
int rv;
|
||||
|
||||
assert(pn_targ->pn_va.va_type == VDIR);
|
||||
|
||||
rv = doremove(pu, opc, targ, pcn->pcn_name);
|
||||
if (rv == 0)
|
||||
puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N2);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
struct puffs_newinfo *pni, const struct puffs_cn *pcn,
|
||||
const struct vattr *va)
|
||||
{
|
||||
PSSHFSAUTOVAR(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct puffs_node *pn_new;
|
||||
|
||||
psbuf_req_str(pb, SSH_FXP_MKDIR, reqid, PCNPATH(pcn));
|
||||
psbuf_put_vattr(pb, va, pctx);
|
||||
GETRESPONSE(pb, pctx->sshfd);
|
||||
|
||||
rv = psbuf_expect_status(pb);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
pn_new = allocnode(pu, pn, pcn->pcn_name, va);
|
||||
if (pn_new) {
|
||||
puffs_newinfo_setcookie(pni, pn_new);
|
||||
} else {
|
||||
struct puffs_framebuf *pb2 = psbuf_makeout();
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_recycleout(pb2);
|
||||
psbuf_req_str(pb2, SSH_FXP_RMDIR, reqid, PCNPATH(pcn));
|
||||
JUSTSEND(pb2, pctx->sshfd);
|
||||
rv = ENOMEM;
|
||||
}
|
||||
|
||||
out:
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
struct puffs_newinfo *pni, const struct puffs_cn *pcn,
|
||||
const struct vattr *va, const char *link_target)
|
||||
{
|
||||
PSSHFSAUTOVAR(pu);
|
||||
struct puffs_node *pn = opc;
|
||||
struct puffs_node *pn_new;
|
||||
|
||||
if (pctx->protover < 3) {
|
||||
rv = EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: ietf says: source, target. openssh says: ietf who?
|
||||
* Let's go with openssh and build quirk tables later if we care
|
||||
*/
|
||||
psbuf_req_str(pb, SSH_FXP_SYMLINK, reqid, link_target);
|
||||
psbuf_put_str(pb, PCNPATH(pcn));
|
||||
GETRESPONSE(pb, pctx->sshfd);
|
||||
|
||||
rv = psbuf_expect_status(pb);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
pn_new = allocnode(pu, pn, pcn->pcn_name, va);
|
||||
if (pn_new) {
|
||||
puffs_newinfo_setcookie(pni, pn_new);
|
||||
} else {
|
||||
struct puffs_framebuf *pb2 = psbuf_makeout();
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_recycleout(pb2);
|
||||
psbuf_req_str(pb2, SSH_FXP_REMOVE, reqid, PCNPATH(pcn));
|
||||
JUSTSEND(pb2, pctx->sshfd);
|
||||
rv = ENOMEM;
|
||||
}
|
||||
|
||||
out:
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
psshfs_node_rename(struct puffs_usermount *pu, puffs_cookie_t opc,
|
||||
puffs_cookie_t src, const struct puffs_cn *pcn_src,
|
||||
puffs_cookie_t targ_dir, puffs_cookie_t targ,
|
||||
const struct puffs_cn *pcn_targ)
|
||||
{
|
||||
PSSHFSAUTOVAR(pu);
|
||||
struct puffs_node *pn_sf = src;
|
||||
struct puffs_node *pn_td = targ_dir, *pn_tf = targ;
|
||||
struct psshfs_node *psn_src = pn_sf->pn_data;
|
||||
struct psshfs_node *psn_targdir = pn_td->pn_data;
|
||||
|
||||
if (pctx->protover < 2) {
|
||||
rv = EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pn_tf) {
|
||||
rv = doremove(pu, targ_dir, pn_tf, pcn_targ->pcn_name);
|
||||
if (rv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
psbuf_req_str(pb, SSH_FXP_RENAME, reqid, PCNPATH(pcn_src));
|
||||
psbuf_put_str(pb, PCNPATH(pcn_targ));
|
||||
GETRESPONSE(pb, pctx->sshfd);
|
||||
|
||||
rv = psbuf_expect_status(pb);
|
||||
if (rv == 0) {
|
||||
struct psshfs_dir *pd;
|
||||
|
||||
/*
|
||||
* XXX: interfaces didn't quite work with rename..
|
||||
* the song remains the same. go figure .. ;)
|
||||
*/
|
||||
nukenode(pn_sf, pcn_src->pcn_name, 0);
|
||||
pd = direnter(pn_td, pcn_targ->pcn_name);
|
||||
pd->entry = pn_sf;
|
||||
puffs_setvattr(&pd->va, &pn_sf->pn_va);
|
||||
|
||||
if (opc != targ_dir) {
|
||||
psn_targdir->childcount++;
|
||||
psn_src->parent = pn_td;
|
||||
if (pn_sf->pn_va.va_type == VDIR)
|
||||
pn_td->pn_va.va_nlink++;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* So this file system happened to be written in such a way that
|
||||
* lookup for ".." is hard if we lose the in-memory node. We'd
|
||||
* need to recreate the entire directory structure from the root
|
||||
* node up to the ".." node we're looking up.
|
||||
*
|
||||
* And since our entire fs structure is purely fictional (i.e. it's
|
||||
* only in-memory, not fetchable from the server), the easiest way
|
||||
* to deal with it is to not allow nodes with children to be
|
||||
* reclaimed.
|
||||
*
|
||||
* If a node with children is being attempted to be reclaimed, we
|
||||
* just mark it "reclaimed" but leave it as is until all its children
|
||||
* have been reclaimed. If a lookup for that node is done meanwhile,
|
||||
* it will be found by lookup() and we just remove the "reclaimed"
|
||||
* bit.
|
||||
*/
|
||||
int
|
||||
psshfs_node_reclaim(struct puffs_usermount *pu, puffs_cookie_t opc)
|
||||
{
|
||||
struct puffs_node *pn = opc, *pn_next, *pn_root;
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
|
||||
/*
|
||||
* don't reclaim if we have file handle issued, otherwise
|
||||
* we can't do fhtonode
|
||||
*/
|
||||
if (psn->stat & PSN_HASFH)
|
||||
return 0;
|
||||
|
||||
psn->stat |= PSN_RECLAIMED;
|
||||
pn_root = puffs_getroot(pu);
|
||||
for (; pn != pn_root; pn = pn_next) {
|
||||
psn = pn->pn_data;
|
||||
if ((psn->stat & PSN_RECLAIMED) == 0 || psn->childcount != 0)
|
||||
break;
|
||||
|
||||
pn_next = psn->parent;
|
||||
doreclaim(pn);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
590
usr.sbin/puffs/mount_psshfs/psbuf.c
Normal file
590
usr.sbin/puffs/mount_psshfs/psbuf.c
Normal file
|
|
@ -0,0 +1,590 @@
|
|||
/* $NetBSD: psbuf.c,v 1.19 2012/11/04 22:46:08 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: psbuf.c,v 1.19 2012/11/04 22:46:08 christos Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
/*
|
||||
* buffering functions for network input/output. slightly different
|
||||
* from the average joe buffer routines, as is usually the case ...
|
||||
* these use efuns for now.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "psshfs.h"
|
||||
#include "sftp_proto.h"
|
||||
|
||||
#define FAILRV(x) do { int rv; if ((rv=x)) return (rv); } while (/*CONSTCOND*/0)
|
||||
#define READSTATE_LENGTH(off) (off < 4)
|
||||
|
||||
#define SFTP_LENOFF 0
|
||||
#define SFTP_TYPEOFF 4
|
||||
#define SFTP_REQIDOFF 5
|
||||
|
||||
#define CHECK(v) if (!(v)) abort()
|
||||
|
||||
uint8_t
|
||||
psbuf_get_type(struct puffs_framebuf *pb)
|
||||
{
|
||||
uint8_t type;
|
||||
|
||||
puffs_framebuf_getdata_atoff(pb, SFTP_TYPEOFF, &type, 1);
|
||||
return type;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
psbuf_get_len(struct puffs_framebuf *pb)
|
||||
{
|
||||
uint32_t len;
|
||||
|
||||
puffs_framebuf_getdata_atoff(pb, SFTP_LENOFF, &len, 4);
|
||||
return be32toh(len);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
psbuf_get_reqid(struct puffs_framebuf *pb)
|
||||
{
|
||||
uint32_t req;
|
||||
|
||||
puffs_framebuf_getdata_atoff(pb, SFTP_REQIDOFF, &req, 4);
|
||||
return be32toh(req);
|
||||
}
|
||||
|
||||
#define CUROFF(pb) (puffs_framebuf_telloff(pb))
|
||||
int
|
||||
psbuf_read(struct puffs_usermount *pu, struct puffs_framebuf *pb,
|
||||
int fd, int *done)
|
||||
{
|
||||
void *win;
|
||||
ssize_t n;
|
||||
size_t howmuch, winlen;
|
||||
int lenstate;
|
||||
|
||||
the_next_level:
|
||||
if ((lenstate = READSTATE_LENGTH(CUROFF(pb))))
|
||||
howmuch = 4 - CUROFF(pb);
|
||||
else
|
||||
howmuch = psbuf_get_len(pb) - (CUROFF(pb) - 4);
|
||||
|
||||
if (puffs_framebuf_reserve_space(pb, howmuch) == -1)
|
||||
return errno;
|
||||
|
||||
while (howmuch) {
|
||||
winlen = howmuch;
|
||||
if (puffs_framebuf_getwindow(pb, CUROFF(pb), &win, &winlen)==-1)
|
||||
return errno;
|
||||
n = recv(fd, win, winlen, MSG_NOSIGNAL);
|
||||
switch (n) {
|
||||
case 0:
|
||||
return ECONNRESET;
|
||||
case -1:
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
return errno;
|
||||
default:
|
||||
howmuch -= n;
|
||||
puffs_framebuf_seekset(pb, CUROFF(pb) + n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lenstate) {
|
||||
/* XXX: initial exchange shorter.. but don't worry, be happy */
|
||||
puffs_framebuf_seekset(pb, 9);
|
||||
*done = 1;
|
||||
return 0;
|
||||
} else
|
||||
goto the_next_level;
|
||||
}
|
||||
|
||||
int
|
||||
psbuf_write(struct puffs_usermount *pu, struct puffs_framebuf *pb,
|
||||
int fd, int *done)
|
||||
{
|
||||
void *win;
|
||||
ssize_t n;
|
||||
size_t winlen, howmuch;
|
||||
|
||||
/* finalize buffer.. could be elsewhere ... */
|
||||
if (CUROFF(pb) == 0) {
|
||||
uint32_t len;
|
||||
|
||||
len = htobe32(puffs_framebuf_tellsize(pb) - 4);
|
||||
puffs_framebuf_putdata_atoff(pb, 0, &len, 4);
|
||||
}
|
||||
|
||||
howmuch = puffs_framebuf_tellsize(pb) - CUROFF(pb);
|
||||
while (howmuch) {
|
||||
winlen = howmuch;
|
||||
if (puffs_framebuf_getwindow(pb, CUROFF(pb), &win, &winlen)==-1)
|
||||
return errno;
|
||||
n = send(fd, win, winlen, MSG_NOSIGNAL);
|
||||
switch (n) {
|
||||
case 0:
|
||||
return ECONNRESET;
|
||||
case -1:
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
return errno;
|
||||
default:
|
||||
howmuch -= n;
|
||||
puffs_framebuf_seekset(pb, CUROFF(pb) + n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*done = 1;
|
||||
return 0;
|
||||
}
|
||||
#undef CUROFF
|
||||
|
||||
int
|
||||
psbuf_cmp(struct puffs_usermount *pu,
|
||||
struct puffs_framebuf *cmp1, struct puffs_framebuf *cmp2, int *notresp)
|
||||
{
|
||||
|
||||
return psbuf_get_reqid(cmp1) != psbuf_get_reqid(cmp2);
|
||||
}
|
||||
|
||||
struct puffs_framebuf *
|
||||
psbuf_makeout()
|
||||
{
|
||||
struct puffs_framebuf *pb;
|
||||
|
||||
pb = puffs_framebuf_make();
|
||||
puffs_framebuf_seekset(pb, 4);
|
||||
return pb;
|
||||
}
|
||||
|
||||
void
|
||||
psbuf_recycleout(struct puffs_framebuf *pb)
|
||||
{
|
||||
|
||||
puffs_framebuf_recycle(pb);
|
||||
puffs_framebuf_seekset(pb, 4);
|
||||
}
|
||||
|
||||
void
|
||||
psbuf_put_1(struct puffs_framebuf *pb, uint8_t val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = puffs_framebuf_putdata(pb, &val, 1);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
void
|
||||
psbuf_put_2(struct puffs_framebuf *pb, uint16_t val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
HTOBE16(val);
|
||||
rv = puffs_framebuf_putdata(pb, &val, 2);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
void
|
||||
psbuf_put_4(struct puffs_framebuf *pb, uint32_t val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
HTOBE32(val);
|
||||
rv = puffs_framebuf_putdata(pb, &val, 4);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
void
|
||||
psbuf_put_8(struct puffs_framebuf *pb, uint64_t val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
HTOBE64(val);
|
||||
rv = puffs_framebuf_putdata(pb, &val, 8);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
void
|
||||
psbuf_put_data(struct puffs_framebuf *pb, const void *data, uint32_t dlen)
|
||||
{
|
||||
int rv;
|
||||
|
||||
psbuf_put_4(pb, dlen);
|
||||
rv = puffs_framebuf_putdata(pb, data, dlen);
|
||||
CHECK(rv == 0);
|
||||
}
|
||||
|
||||
void
|
||||
psbuf_put_str(struct puffs_framebuf *pb, const char *str)
|
||||
{
|
||||
|
||||
psbuf_put_data(pb, str, strlen(str));
|
||||
}
|
||||
|
||||
void
|
||||
psbuf_put_vattr(struct puffs_framebuf *pb, const struct vattr *va,
|
||||
const struct psshfs_ctx *pctx)
|
||||
{
|
||||
uint32_t flags;
|
||||
uint32_t theuid = -1, thegid = -1;
|
||||
flags = 0;
|
||||
|
||||
if (va->va_size != (uint64_t)PUFFS_VNOVAL)
|
||||
flags |= SSH_FILEXFER_ATTR_SIZE;
|
||||
if (va->va_uid != (uid_t)PUFFS_VNOVAL) {
|
||||
theuid = va->va_uid;
|
||||
if (pctx->domangleuid && theuid == pctx->myuid)
|
||||
theuid = pctx->mangleuid;
|
||||
flags |= SSH_FILEXFER_ATTR_UIDGID;
|
||||
}
|
||||
if (va->va_gid != (gid_t)PUFFS_VNOVAL) {
|
||||
thegid = va->va_gid;
|
||||
if (pctx->domanglegid && thegid == pctx->mygid)
|
||||
thegid = pctx->manglegid;
|
||||
flags |= SSH_FILEXFER_ATTR_UIDGID;
|
||||
}
|
||||
if (va->va_mode != (mode_t)PUFFS_VNOVAL)
|
||||
flags |= SSH_FILEXFER_ATTR_PERMISSIONS;
|
||||
|
||||
if (va->va_atime.tv_sec != PUFFS_VNOVAL)
|
||||
flags |= SSH_FILEXFER_ATTR_ACCESSTIME;
|
||||
|
||||
psbuf_put_4(pb, flags);
|
||||
if (flags & SSH_FILEXFER_ATTR_SIZE)
|
||||
psbuf_put_8(pb, va->va_size);
|
||||
if (flags & SSH_FILEXFER_ATTR_UIDGID) {
|
||||
psbuf_put_4(pb, theuid);
|
||||
psbuf_put_4(pb, thegid);
|
||||
}
|
||||
if (flags & SSH_FILEXFER_ATTR_PERMISSIONS)
|
||||
psbuf_put_4(pb, va->va_mode);
|
||||
|
||||
/* XXX: this is totally wrong for protocol v3, see OpenSSH */
|
||||
if (flags & SSH_FILEXFER_ATTR_ACCESSTIME) {
|
||||
psbuf_put_4(pb, va->va_atime.tv_sec);
|
||||
psbuf_put_4(pb, va->va_mtime.tv_sec);
|
||||
}
|
||||
}
|
||||
|
||||
#define ERETURN(rv) return ((rv) == -1 ? errno : 0)
|
||||
|
||||
int
|
||||
psbuf_get_1(struct puffs_framebuf *pb, uint8_t *val)
|
||||
{
|
||||
|
||||
ERETURN(puffs_framebuf_getdata(pb, val, 1));
|
||||
}
|
||||
|
||||
int
|
||||
psbuf_get_2(struct puffs_framebuf *pb, uint16_t *val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = puffs_framebuf_getdata(pb, val, 2);
|
||||
BE16TOH(*val);
|
||||
|
||||
ERETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
psbuf_get_4(struct puffs_framebuf *pb, uint32_t *val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = puffs_framebuf_getdata(pb, val, 4);
|
||||
BE32TOH(*val);
|
||||
|
||||
ERETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
psbuf_get_8(struct puffs_framebuf *pb, uint64_t *val)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = puffs_framebuf_getdata(pb, val, 8);
|
||||
BE64TOH(*val);
|
||||
|
||||
ERETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
psbuf_get_str(struct puffs_framebuf *pb, char **strp, uint32_t *strlenp)
|
||||
{
|
||||
char *str;
|
||||
uint32_t len;
|
||||
|
||||
FAILRV(psbuf_get_4(pb, &len));
|
||||
|
||||
if (puffs_framebuf_remaining(pb) < len)
|
||||
return EPROTO;
|
||||
|
||||
str = emalloc(len+1);
|
||||
puffs_framebuf_getdata(pb, str, len);
|
||||
str[len] = '\0';
|
||||
*strp = str;
|
||||
|
||||
if (strlenp)
|
||||
*strlenp = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
psbuf_get_vattr(struct puffs_framebuf *pb, struct vattr *vap)
|
||||
{
|
||||
uint32_t flags;
|
||||
uint32_t val;
|
||||
|
||||
puffs_vattr_null(vap);
|
||||
|
||||
FAILRV(psbuf_get_4(pb, &flags));
|
||||
|
||||
if (flags & SSH_FILEXFER_ATTR_SIZE) {
|
||||
FAILRV(psbuf_get_8(pb, &vap->va_size));
|
||||
vap->va_bytes = vap->va_size;
|
||||
}
|
||||
if (flags & SSH_FILEXFER_ATTR_UIDGID) {
|
||||
FAILRV(psbuf_get_4(pb, &vap->va_uid));
|
||||
FAILRV(psbuf_get_4(pb, &vap->va_gid));
|
||||
}
|
||||
if (flags & SSH_FILEXFER_ATTR_PERMISSIONS) {
|
||||
FAILRV(psbuf_get_4(pb, &vap->va_mode));
|
||||
vap->va_type = puffs_mode2vt(vap->va_mode);
|
||||
}
|
||||
if (flags & SSH_FILEXFER_ATTR_ACCESSTIME) {
|
||||
/*
|
||||
* XXX: this is utterly wrong if we want to speak
|
||||
* protocol version 3, but it seems like the
|
||||
* "internet standard" for doing this
|
||||
*/
|
||||
FAILRV(psbuf_get_4(pb, &val));
|
||||
vap->va_atime.tv_sec = val;
|
||||
FAILRV(psbuf_get_4(pb, &val));
|
||||
vap->va_mtime.tv_sec = val;
|
||||
/* make ctime the same as mtime */
|
||||
vap->va_ctime.tv_sec = val;
|
||||
|
||||
vap->va_atime.tv_nsec = 0;
|
||||
vap->va_ctime.tv_nsec = 0;
|
||||
vap->va_mtime.tv_nsec = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Buffer content helpers. Caller frees all data.
|
||||
*/
|
||||
|
||||
/*
|
||||
* error mapping.. most are not expected for a file system, but
|
||||
* should help with diagnosing a possible error
|
||||
*/
|
||||
static int emap[] = {
|
||||
0, /* OK */
|
||||
0, /* EOF */
|
||||
ENOENT, /* NO_SUCH_FILE */
|
||||
EPERM, /* PERMISSION_DENIED */
|
||||
EIO, /* FAILURE */
|
||||
EBADMSG, /* BAD_MESSAGE */
|
||||
ENOTCONN, /* NO_CONNECTION */
|
||||
ECONNRESET, /* CONNECTION_LOST */
|
||||
EOPNOTSUPP, /* OP_UNSUPPORTED */
|
||||
EINVAL, /* INVALID_HANDLE */
|
||||
ENXIO, /* NO_SUCH_PATH */
|
||||
EEXIST, /* FILE_ALREADY_EXISTS */
|
||||
ENODEV /* WRITE_PROTECT */
|
||||
};
|
||||
#define NERRORS ((int)(sizeof(emap) / sizeof(emap[0])))
|
||||
|
||||
static int
|
||||
sftperr_to_errno(int error)
|
||||
{
|
||||
|
||||
if (!error)
|
||||
return 0;
|
||||
|
||||
if (error >= NERRORS || error < 0)
|
||||
return EPROTO;
|
||||
|
||||
return emap[error];
|
||||
}
|
||||
|
||||
#define INVALRESPONSE EPROTO
|
||||
|
||||
static int
|
||||
expectcode(struct puffs_framebuf *pb, int value)
|
||||
{
|
||||
uint32_t error;
|
||||
uint8_t type;
|
||||
|
||||
type = psbuf_get_type(pb);
|
||||
if (type == value)
|
||||
return 0;
|
||||
|
||||
if (type != SSH_FXP_STATUS)
|
||||
return INVALRESPONSE;
|
||||
|
||||
FAILRV(psbuf_get_4(pb, &error));
|
||||
|
||||
return sftperr_to_errno(error);
|
||||
}
|
||||
|
||||
#define CHECKCODE(pb,val) \
|
||||
do { \
|
||||
int rv; \
|
||||
rv = expectcode(pb, val); \
|
||||
if (rv) \
|
||||
return rv; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
int
|
||||
psbuf_expect_status(struct puffs_framebuf *pb)
|
||||
{
|
||||
uint32_t error;
|
||||
|
||||
if (psbuf_get_type(pb) != SSH_FXP_STATUS)
|
||||
return INVALRESPONSE;
|
||||
|
||||
FAILRV(psbuf_get_4(pb, &error));
|
||||
|
||||
return sftperr_to_errno(error);
|
||||
}
|
||||
|
||||
int
|
||||
psbuf_expect_handle(struct puffs_framebuf *pb, char **hand, uint32_t *handlen)
|
||||
{
|
||||
|
||||
CHECKCODE(pb, SSH_FXP_HANDLE);
|
||||
FAILRV(psbuf_get_str(pb, hand, handlen));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* no memory allocation, direct copy */
|
||||
int
|
||||
psbuf_do_data(struct puffs_framebuf *pb, uint8_t *data, uint32_t *dlen)
|
||||
{
|
||||
void *win;
|
||||
size_t bufoff, winlen;
|
||||
uint32_t len, dataoff;
|
||||
|
||||
if (psbuf_get_type(pb) != SSH_FXP_DATA) {
|
||||
uint32_t val;
|
||||
|
||||
if (psbuf_get_type(pb) != SSH_FXP_STATUS)
|
||||
return INVALRESPONSE;
|
||||
|
||||
if (psbuf_get_4(pb, &val) != 0)
|
||||
return INVALRESPONSE;
|
||||
|
||||
if (val != SSH_FX_EOF)
|
||||
return sftperr_to_errno(val);
|
||||
|
||||
*dlen = 0;
|
||||
return 0;
|
||||
}
|
||||
if (psbuf_get_4(pb, &len) != 0)
|
||||
return INVALRESPONSE;
|
||||
|
||||
if (*dlen < len)
|
||||
return EINVAL;
|
||||
|
||||
*dlen = 0;
|
||||
|
||||
dataoff = 0;
|
||||
while (dataoff < len) {
|
||||
winlen = len-dataoff;
|
||||
bufoff = puffs_framebuf_telloff(pb);
|
||||
if (puffs_framebuf_getwindow(pb, bufoff,
|
||||
&win, &winlen) == -1)
|
||||
return EINVAL;
|
||||
if (winlen == 0)
|
||||
break;
|
||||
|
||||
memcpy(data + dataoff, win, winlen);
|
||||
dataoff += winlen;
|
||||
}
|
||||
|
||||
*dlen = dataoff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
psbuf_expect_name(struct puffs_framebuf *pb, uint32_t *count)
|
||||
{
|
||||
|
||||
CHECKCODE(pb, SSH_FXP_NAME);
|
||||
FAILRV(psbuf_get_4(pb, count));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
psbuf_expect_attrs(struct puffs_framebuf *pb, struct vattr *vap)
|
||||
{
|
||||
|
||||
CHECKCODE(pb, SSH_FXP_ATTRS);
|
||||
FAILRV(psbuf_get_vattr(pb, vap));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* More helpers: larger-scale put functions
|
||||
*/
|
||||
|
||||
void
|
||||
psbuf_req_data(struct puffs_framebuf *pb, int type, uint32_t reqid,
|
||||
const void *data, uint32_t dlen)
|
||||
{
|
||||
|
||||
psbuf_put_1(pb, type);
|
||||
psbuf_put_4(pb, reqid);
|
||||
psbuf_put_data(pb, data, dlen);
|
||||
}
|
||||
|
||||
void
|
||||
psbuf_req_str(struct puffs_framebuf *pb, int type, uint32_t reqid,
|
||||
const char *str)
|
||||
{
|
||||
|
||||
psbuf_req_data(pb, type, reqid, str, strlen(str));
|
||||
}
|
||||
501
usr.sbin/puffs/mount_psshfs/psshfs.c
Normal file
501
usr.sbin/puffs/mount_psshfs/psshfs.c
Normal file
|
|
@ -0,0 +1,501 @@
|
|||
/* $NetBSD: psshfs.c,v 1.66 2012/11/04 22:46:08 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* psshfs: puffs sshfs
|
||||
*
|
||||
* psshfs implements sshfs functionality on top of puffs making it
|
||||
* possible to mount a filesystme through the sftp service.
|
||||
*
|
||||
* psshfs can execute multiple operations in "parallel" by using the
|
||||
* puffs_cc framework for continuations.
|
||||
*
|
||||
* Concurrency control is handled currently by vnode locking (this
|
||||
* will change in the future). Context switch locations are easy to
|
||||
* find by grepping for puffs_framebuf_enqueue_cc().
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: psshfs.c,v 1.66 2012/11/04 22:46:08 christos Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <mntopts.h>
|
||||
#include <paths.h>
|
||||
#include <poll.h>
|
||||
#include <puffs.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "psshfs.h"
|
||||
|
||||
static int pssh_connect(struct puffs_usermount *, int);
|
||||
static void psshfs_loopfn(struct puffs_usermount *);
|
||||
__dead static void usage(void);
|
||||
static char * cleanhostname(char *);
|
||||
static char * colon(char *);
|
||||
static void add_ssharg(char ***, int *, const char *);
|
||||
static void psshfs_notify(struct puffs_usermount *, int, int);
|
||||
|
||||
#define SSH_PATH "/usr/bin/ssh"
|
||||
|
||||
unsigned int max_reads;
|
||||
static int sighup;
|
||||
|
||||
static char *
|
||||
cleanhostname(char *host)
|
||||
{
|
||||
if (*host == '[' && host[strlen(host) - 1] == ']') {
|
||||
host[strlen(host) - 1] = '\0';
|
||||
return (host + 1);
|
||||
} else
|
||||
return host;
|
||||
}
|
||||
|
||||
static char *
|
||||
colon(char *cp)
|
||||
{
|
||||
int flag = 0;
|
||||
|
||||
if (*cp == '[')
|
||||
flag = 1;
|
||||
|
||||
for (; *cp; ++cp) {
|
||||
if (*cp == '@' && *(cp+1) == '[')
|
||||
flag = 1;
|
||||
if (*cp == ']' && *(cp+1) == ':' && flag)
|
||||
return (cp+1);
|
||||
if (*cp == ':' && !flag)
|
||||
return (cp);
|
||||
if (*cp == '/')
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
add_ssharg(char ***sshargs, int *nargs, const char *arg)
|
||||
{
|
||||
|
||||
*sshargs = realloc(*sshargs, (*nargs + 2) * sizeof(char*));
|
||||
if (!*sshargs)
|
||||
err(1, "realloc");
|
||||
(*sshargs)[(*nargs)++] = estrdup(arg);
|
||||
(*sshargs)[*nargs] = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: %s "
|
||||
"[-ceprst] [-F configfile] [-O sshopt=value] [-o opts] "
|
||||
"user@host:path mountpath\n",
|
||||
getprogname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
takehup(int sig)
|
||||
{
|
||||
|
||||
sighup = 1;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct psshfs_ctx pctx;
|
||||
struct puffs_usermount *pu;
|
||||
struct puffs_ops *pops;
|
||||
struct psshfs_node *root = &pctx.psn_root;
|
||||
struct puffs_node *pn_root;
|
||||
puffs_framev_fdnotify_fn notfn;
|
||||
struct vattr *rva;
|
||||
mntoptparse_t mp;
|
||||
char **sshargs;
|
||||
char *user;
|
||||
char *host;
|
||||
char *path;
|
||||
int mntflags, pflags, ch;
|
||||
int detach;
|
||||
int exportfs, refreshival, numconnections;
|
||||
int nargs;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
if (argc < 3)
|
||||
usage();
|
||||
|
||||
memset(&pctx, 0, sizeof(pctx));
|
||||
mntflags = pflags = exportfs = nargs = 0;
|
||||
numconnections = 1;
|
||||
detach = 1;
|
||||
refreshival = DEFAULTREFRESH;
|
||||
notfn = puffs_framev_unmountonclose;
|
||||
sshargs = NULL;
|
||||
add_ssharg(&sshargs, &nargs, SSH_PATH);
|
||||
add_ssharg(&sshargs, &nargs, "-axs");
|
||||
add_ssharg(&sshargs, &nargs, "-oClearAllForwardings=yes");
|
||||
|
||||
while ((ch = getopt(argc, argv, "c:eF:g:o:O:pr:st:u:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
numconnections = atoi(optarg);
|
||||
if (numconnections < 1 || numconnections > 2) {
|
||||
fprintf(stderr, "%s: only 1 or 2 connections "
|
||||
"permitted currently\n", getprogname());
|
||||
usage();
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
exportfs = 1;
|
||||
break;
|
||||
case 'F':
|
||||
add_ssharg(&sshargs, &nargs, "-F");
|
||||
add_ssharg(&sshargs, &nargs, optarg);
|
||||
break;
|
||||
case 'g':
|
||||
pctx.domanglegid = 1;
|
||||
pctx.manglegid = atoi(optarg);
|
||||
if (pctx.manglegid == (gid_t)-1)
|
||||
errx(1, "-1 not allowed for -g");
|
||||
pctx.mygid = getegid();
|
||||
break;
|
||||
case 'O':
|
||||
add_ssharg(&sshargs, &nargs, "-o");
|
||||
add_ssharg(&sshargs, &nargs, optarg);
|
||||
break;
|
||||
case 'o':
|
||||
mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags);
|
||||
if (mp == NULL)
|
||||
err(1, "getmntopts");
|
||||
freemntopts(mp);
|
||||
break;
|
||||
case 'p':
|
||||
notfn = psshfs_notify;
|
||||
break;
|
||||
case 'r':
|
||||
max_reads = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
detach = 0;
|
||||
break;
|
||||
case 't':
|
||||
refreshival = atoi(optarg);
|
||||
if (refreshival < 0 && refreshival != -1)
|
||||
errx(1, "invalid timeout %d", refreshival);
|
||||
break;
|
||||
case 'u':
|
||||
pctx.domangleuid = 1;
|
||||
pctx.mangleuid = atoi(optarg);
|
||||
if (pctx.mangleuid == (uid_t)-1)
|
||||
errx(1, "-1 not allowed for -u");
|
||||
pctx.myuid = geteuid();
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (pflags & PUFFS_FLAG_OPDUMP)
|
||||
detach = 0;
|
||||
pflags |= PUFFS_FLAG_BUILDPATH;
|
||||
pflags |= PUFFS_KFLAG_WTCACHE | PUFFS_KFLAG_IAONDEMAND;
|
||||
|
||||
if (argc != 2)
|
||||
usage();
|
||||
|
||||
PUFFSOP_INIT(pops);
|
||||
|
||||
PUFFSOP_SET(pops, psshfs, fs, unmount);
|
||||
PUFFSOP_SETFSNOP(pops, sync); /* XXX */
|
||||
PUFFSOP_SET(pops, psshfs, fs, statvfs);
|
||||
PUFFSOP_SET(pops, psshfs, fs, nodetofh);
|
||||
PUFFSOP_SET(pops, psshfs, fs, fhtonode);
|
||||
|
||||
PUFFSOP_SET(pops, psshfs, node, lookup);
|
||||
PUFFSOP_SET(pops, psshfs, node, create);
|
||||
PUFFSOP_SET(pops, psshfs, node, open);
|
||||
PUFFSOP_SET(pops, psshfs, node, inactive);
|
||||
PUFFSOP_SET(pops, psshfs, node, readdir);
|
||||
PUFFSOP_SET(pops, psshfs, node, getattr);
|
||||
PUFFSOP_SET(pops, psshfs, node, setattr);
|
||||
PUFFSOP_SET(pops, psshfs, node, mkdir);
|
||||
PUFFSOP_SET(pops, psshfs, node, remove);
|
||||
PUFFSOP_SET(pops, psshfs, node, readlink);
|
||||
PUFFSOP_SET(pops, psshfs, node, rmdir);
|
||||
PUFFSOP_SET(pops, psshfs, node, symlink);
|
||||
PUFFSOP_SET(pops, psshfs, node, rename);
|
||||
PUFFSOP_SET(pops, psshfs, node, read);
|
||||
PUFFSOP_SET(pops, psshfs, node, write);
|
||||
PUFFSOP_SET(pops, psshfs, node, reclaim);
|
||||
|
||||
pu = puffs_init(pops, argv[0], "psshfs", &pctx, pflags);
|
||||
if (pu == NULL)
|
||||
err(1, "puffs_init");
|
||||
|
||||
pctx.mounttime = time(NULL);
|
||||
pctx.refreshival = refreshival;
|
||||
pctx.numconnections = numconnections;
|
||||
|
||||
user = strdup(argv[0]);
|
||||
if ((host = strrchr(user, '@')) == NULL) {
|
||||
host = user;
|
||||
} else {
|
||||
*host++ = '\0'; /* break at the '@' */
|
||||
if (user[0] == '\0') {
|
||||
fprintf(stderr, "Missing username\n");
|
||||
usage();
|
||||
}
|
||||
add_ssharg(&sshargs, &nargs, "-l");
|
||||
add_ssharg(&sshargs, &nargs, user);
|
||||
}
|
||||
|
||||
if ((path = colon(host)) != NULL) {
|
||||
*path++ = '\0'; /* break at the ':' */
|
||||
pctx.mountpath = path;
|
||||
} else {
|
||||
pctx.mountpath = ".";
|
||||
}
|
||||
|
||||
host = cleanhostname(host);
|
||||
if (host[0] == '\0') {
|
||||
fprintf(stderr, "Missing hostname\n");
|
||||
usage();
|
||||
}
|
||||
|
||||
add_ssharg(&sshargs, &nargs, host);
|
||||
add_ssharg(&sshargs, &nargs, "sftp");
|
||||
pctx.sshargs = sshargs;
|
||||
|
||||
pctx.nextino = 2;
|
||||
memset(root, 0, sizeof(struct psshfs_node));
|
||||
TAILQ_INIT(&root->pw);
|
||||
pn_root = puffs_pn_new(pu, root);
|
||||
if (pn_root == NULL)
|
||||
return errno;
|
||||
puffs_setroot(pu, pn_root);
|
||||
|
||||
puffs_framev_init(pu, psbuf_read, psbuf_write, psbuf_cmp, NULL, notfn);
|
||||
|
||||
signal(SIGHUP, takehup);
|
||||
puffs_ml_setloopfn(pu, psshfs_loopfn);
|
||||
if (pssh_connect(pu, PSSHFD_META) == -1)
|
||||
err(1, "can't connect meta");
|
||||
if (puffs_framev_addfd(pu, pctx.sshfd,
|
||||
PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
|
||||
err(1, "framebuf addfd meta");
|
||||
if (numconnections == 2) {
|
||||
if (pssh_connect(pu, PSSHFD_DATA) == -1)
|
||||
err(1, "can't connect data");
|
||||
if (puffs_framev_addfd(pu, pctx.sshfd_data,
|
||||
PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
|
||||
err(1, "framebuf addfd data");
|
||||
} else {
|
||||
pctx.sshfd_data = pctx.sshfd;
|
||||
}
|
||||
|
||||
if (exportfs)
|
||||
puffs_setfhsize(pu, sizeof(struct psshfs_fid),
|
||||
PUFFS_FHFLAG_NFSV2 | PUFFS_FHFLAG_NFSV3);
|
||||
|
||||
rva = &pn_root->pn_va;
|
||||
rva->va_fileid = pctx.nextino++;
|
||||
|
||||
/*
|
||||
* For root link count, just guess something ridiculously high.
|
||||
* Guessing too high has no known adverse effects, but fts(3)
|
||||
* doesn't like too low values. This guess will be replaced
|
||||
* with the real value when readdir is first called for
|
||||
* the root directory.
|
||||
*/
|
||||
rva->va_nlink = 8811;
|
||||
|
||||
if (detach)
|
||||
if (puffs_daemon(pu, 1, 1) == -1)
|
||||
err(1, "puffs_daemon");
|
||||
|
||||
if (puffs_mount(pu, argv[1], mntflags, puffs_getroot(pu)) == -1)
|
||||
err(1, "puffs_mount");
|
||||
if (puffs_setblockingmode(pu, PUFFSDEV_NONBLOCK) == -1)
|
||||
err(1, "setblockingmode");
|
||||
|
||||
if (puffs_mainloop(pu) == -1)
|
||||
err(1, "mainloop");
|
||||
puffs_exit(pu, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RETRY_MAX 100
|
||||
|
||||
void
|
||||
psshfs_notify(struct puffs_usermount *pu, int fd, int what)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
int nretry, which, newfd, dummy;
|
||||
|
||||
if (fd == pctx->sshfd) {
|
||||
which = PSSHFD_META;
|
||||
} else {
|
||||
assert(fd == pctx->sshfd_data);
|
||||
which = PSSHFD_DATA;
|
||||
}
|
||||
|
||||
if (puffs_getstate(pu) != PUFFS_STATE_RUNNING)
|
||||
return;
|
||||
|
||||
if (what != (PUFFS_FBIO_READ | PUFFS_FBIO_WRITE)) {
|
||||
puffs_framev_removefd(pu, fd, ECONNRESET);
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
/* deal with zmobies, beware of half-eaten brain */
|
||||
while (waitpid(-1, &dummy, WNOHANG) > 0)
|
||||
continue;
|
||||
|
||||
for (nretry = 0;;nretry++) {
|
||||
if ((newfd = pssh_connect(pu, which)) == -1)
|
||||
goto retry2;
|
||||
|
||||
if (puffs_framev_addfd(pu, newfd,
|
||||
PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
|
||||
goto retry1;
|
||||
|
||||
break;
|
||||
retry1:
|
||||
fprintf(stderr, "reconnect failed... ");
|
||||
close(newfd);
|
||||
retry2:
|
||||
if (nretry < RETRY_MAX) {
|
||||
fprintf(stderr, "retry (%d left)\n", RETRY_MAX-nretry);
|
||||
sleep(nretry);
|
||||
} else {
|
||||
fprintf(stderr, "retry count exceeded, going south\n");
|
||||
exit(1); /* XXXXXXX */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pssh_connect(struct puffs_usermount *pu, int which)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
char * const *sshargs = pctx->sshargs;
|
||||
int fds[2];
|
||||
pid_t pid;
|
||||
int dnfd, x;
|
||||
int *sshfd;
|
||||
pid_t *sshpid;
|
||||
|
||||
if (which == PSSHFD_META) {
|
||||
sshfd = &pctx->sshfd;
|
||||
sshpid = &pctx->sshpid;
|
||||
} else {
|
||||
assert(which == PSSHFD_DATA);
|
||||
sshfd = &pctx->sshfd_data;
|
||||
sshpid = &pctx->sshpid_data;
|
||||
}
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1)
|
||||
return -1;
|
||||
|
||||
pid = fork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
return -1;
|
||||
/*NOTREACHED*/
|
||||
case 0: /* child */
|
||||
if (dup2(fds[0], STDIN_FILENO) == -1)
|
||||
err(1, "child dup2");
|
||||
if (dup2(fds[0], STDOUT_FILENO) == -1)
|
||||
err(1, "child dup2");
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
|
||||
dnfd = open(_PATH_DEVNULL, O_RDWR);
|
||||
if (dnfd != -1)
|
||||
dup2(dnfd, STDERR_FILENO);
|
||||
|
||||
execvp(sshargs[0], sshargs);
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
default:
|
||||
*sshpid = pid;
|
||||
*sshfd = fds[1];
|
||||
close(fds[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (psshfs_handshake(pu, *sshfd) != 0)
|
||||
errx(1, "handshake failed, server does not support sftp?");
|
||||
x = 1;
|
||||
if (ioctl(*sshfd, FIONBIO, &x) == -1)
|
||||
err(1, "nonblocking descriptor %d", which);
|
||||
|
||||
return *sshfd;
|
||||
}
|
||||
|
||||
static void *
|
||||
invalone(struct puffs_usermount *pu, struct puffs_node *pn, void *arg)
|
||||
{
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
|
||||
psn->attrread = 0;
|
||||
psn->dentread = 0;
|
||||
psn->slread = 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
psshfs_loopfn(struct puffs_usermount *pu)
|
||||
{
|
||||
|
||||
if (sighup) {
|
||||
puffs_pn_nodewalk(pu, invalone, NULL);
|
||||
sighup = 0;
|
||||
}
|
||||
}
|
||||
248
usr.sbin/puffs/mount_psshfs/psshfs.h
Normal file
248
usr.sbin/puffs/mount_psshfs/psshfs.h
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/* $NetBSD: psshfs.h,v 1.40 2010/04/01 02:34:09 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef PSSHFS_H_
|
||||
#define PSSHFS_H_
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <puffs.h>
|
||||
|
||||
extern unsigned int max_reads;
|
||||
|
||||
/*
|
||||
* Later protocol versions would have some advantages (such as link count
|
||||
* supported directly as a part of stat), but since proto version 3 seems
|
||||
* to be the only widely available version, let's not try to jump through
|
||||
* too many hoops to be compatible with all versions.
|
||||
*/
|
||||
#define SFTP_PROTOVERSION 3
|
||||
|
||||
/* extensions, held in psshfs_ctx extensions */
|
||||
#define SFTP_EXT_POSIX_RENAME 0x01
|
||||
#define SFTP_EXT_STATVFS 0x02
|
||||
#define SFTP_EXT_FSTATVFS 0x04
|
||||
|
||||
#define DEFAULTREFRESH 30
|
||||
#define REFRESHTIMEOUT(pctx, t) \
|
||||
(!(pctx)->refreshival || ((pctx->refreshival!=-1) && ((t)>pctx->refreshival)))
|
||||
|
||||
PUFFSOP_PROTOS(psshfs);
|
||||
|
||||
#define NEXTREQ(pctx) ((pctx->nextreq)++)
|
||||
#define PSSHFSAUTOVAR(pu) \
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu); \
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu); \
|
||||
uint32_t reqid = NEXTREQ(pctx); \
|
||||
struct puffs_framebuf *pb = psbuf_makeout(); \
|
||||
int rv = 0
|
||||
|
||||
#define PSSHFSRETURN(rv) \
|
||||
puffs_framebuf_destroy(pb); \
|
||||
return (rv)
|
||||
|
||||
#define GETRESPONSE(pb, fd) \
|
||||
do { \
|
||||
if (puffs_framev_enqueue_cc(pcc, fd, pb, 0) == -1) { \
|
||||
rv = errno; \
|
||||
goto out; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define JUSTSEND(pb,fd) \
|
||||
do { \
|
||||
if (puffs_framev_enqueue_justsend(pu, fd, pb, 1, 0) == -1) { \
|
||||
rv = errno; \
|
||||
goto out; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SENDCB(pb, fd, f, a) \
|
||||
do { \
|
||||
if (puffs_framev_enqueue_cb(pu, fd, pb, f, a, 0) == -1) { \
|
||||
rv = errno; \
|
||||
goto out; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
struct psshfs_dir {
|
||||
int valid;
|
||||
struct puffs_node *entry;
|
||||
|
||||
char *entryname;
|
||||
struct vattr va;
|
||||
time_t attrread;
|
||||
};
|
||||
|
||||
struct psshfs_fid {
|
||||
time_t mounttime;
|
||||
struct puffs_node *node;
|
||||
};
|
||||
|
||||
struct psshfs_wait {
|
||||
struct puffs_cc *pw_cc;
|
||||
int pw_type;
|
||||
TAILQ_ENTRY(psshfs_wait) pw_entries;
|
||||
};
|
||||
#define PWTYPE_READDIR 1
|
||||
#define PWTYPE_READ1 2
|
||||
#define PWTYPE_READ2 3
|
||||
#define PWTYPE_WRITE 4
|
||||
|
||||
struct psshfs_node {
|
||||
struct puffs_node *parent;
|
||||
|
||||
struct psshfs_dir *dir; /* only valid if we're of type VDIR */
|
||||
|
||||
size_t denttot;
|
||||
size_t dentnext;
|
||||
time_t dentread;
|
||||
int childcount;
|
||||
|
||||
int stat;
|
||||
unsigned readcount;
|
||||
|
||||
time_t attrread;
|
||||
char *symlink;
|
||||
time_t slread;
|
||||
|
||||
char *fhand_r;
|
||||
char *fhand_w;
|
||||
uint32_t fhand_r_len;
|
||||
uint32_t fhand_w_len;
|
||||
struct puffs_framebuf *lazyopen_r;
|
||||
struct puffs_framebuf *lazyopen_w;
|
||||
int lazyopen_err_r, lazyopen_err_w;
|
||||
|
||||
TAILQ_HEAD(, psshfs_wait) pw;
|
||||
};
|
||||
#define PSN_RECLAIMED 0x01
|
||||
#define PSN_HASFH 0x02
|
||||
#define PSN_READDIR 0x04
|
||||
#define PSN_DOLAZY_R 0x08
|
||||
#define PSN_DOLAZY_W 0x10
|
||||
#define PSN_LAZYWAIT_R 0x20
|
||||
#define PSN_LAZYWAIT_W 0x40
|
||||
#define PSN_HANDLECLOSE 0x80
|
||||
|
||||
#define HANDLE_READ 0x1
|
||||
#define HANDLE_WRITE 0x2
|
||||
|
||||
struct psshfs_ctx {
|
||||
int numconnections;
|
||||
int sshfd;
|
||||
int sshfd_data;
|
||||
pid_t sshpid;
|
||||
pid_t sshpid_data;
|
||||
|
||||
const char *mountpath;
|
||||
char **sshargs;
|
||||
|
||||
int protover;
|
||||
int extensions;
|
||||
|
||||
uint32_t nextreq;
|
||||
|
||||
struct puffs_framebuf *curpb;
|
||||
|
||||
struct psshfs_node psn_root;
|
||||
ino_t nextino;
|
||||
|
||||
int canexport;
|
||||
time_t mounttime;
|
||||
|
||||
int refreshival;
|
||||
|
||||
int domangleuid, domanglegid;
|
||||
uid_t mangleuid, myuid;
|
||||
gid_t manglegid, mygid;
|
||||
};
|
||||
#define PSSHFD_META 0
|
||||
#define PSSHFD_DATA 1
|
||||
|
||||
int psshfs_handshake(struct puffs_usermount *, int);
|
||||
|
||||
int psbuf_read(struct puffs_usermount *, struct puffs_framebuf *,int,int*);
|
||||
int psbuf_write(struct puffs_usermount *, struct puffs_framebuf *,int,int*);
|
||||
int psbuf_cmp(struct puffs_usermount *,
|
||||
struct puffs_framebuf *, struct puffs_framebuf *, int *);
|
||||
|
||||
struct puffs_framebuf *psbuf_makeout(void);
|
||||
void psbuf_recycleout(struct puffs_framebuf *);
|
||||
|
||||
void psbuf_put_1(struct puffs_framebuf *, uint8_t);
|
||||
void psbuf_put_2(struct puffs_framebuf *, uint16_t);
|
||||
void psbuf_put_4(struct puffs_framebuf *, uint32_t);
|
||||
void psbuf_put_8(struct puffs_framebuf *, uint64_t);
|
||||
void psbuf_put_str(struct puffs_framebuf *, const char *);
|
||||
void psbuf_put_data(struct puffs_framebuf *, const void *, uint32_t);
|
||||
void psbuf_put_vattr(struct puffs_framebuf *, const struct vattr *,
|
||||
const struct psshfs_ctx *);
|
||||
|
||||
uint8_t psbuf_get_type(struct puffs_framebuf *);
|
||||
uint32_t psbuf_get_len(struct puffs_framebuf *);
|
||||
uint32_t psbuf_get_reqid(struct puffs_framebuf *);
|
||||
|
||||
int psbuf_get_1(struct puffs_framebuf *, uint8_t *);
|
||||
int psbuf_get_2(struct puffs_framebuf *, uint16_t *);
|
||||
int psbuf_get_4(struct puffs_framebuf *, uint32_t *);
|
||||
int psbuf_get_8(struct puffs_framebuf *, uint64_t *);
|
||||
int psbuf_get_str(struct puffs_framebuf *, char **, uint32_t *);
|
||||
int psbuf_get_vattr(struct puffs_framebuf *, struct vattr *);
|
||||
|
||||
int psbuf_expect_status(struct puffs_framebuf *);
|
||||
int psbuf_expect_handle(struct puffs_framebuf *, char **, uint32_t *);
|
||||
int psbuf_expect_name(struct puffs_framebuf *, uint32_t *);
|
||||
int psbuf_expect_attrs(struct puffs_framebuf *, struct vattr *);
|
||||
|
||||
int psbuf_do_data(struct puffs_framebuf *, uint8_t *, uint32_t *);
|
||||
|
||||
void psbuf_req_data(struct puffs_framebuf *, int, uint32_t,
|
||||
const void *, uint32_t);
|
||||
void psbuf_req_str(struct puffs_framebuf *, int, uint32_t, const char *);
|
||||
|
||||
int sftp_readdir(struct puffs_usermount *, struct psshfs_ctx *,
|
||||
struct puffs_node *);
|
||||
|
||||
struct psshfs_dir *lookup(struct psshfs_dir *, size_t, const char *);
|
||||
struct puffs_node *makenode(struct puffs_usermount *, struct puffs_node *,
|
||||
const struct psshfs_dir *, const struct vattr *);
|
||||
struct puffs_node *allocnode(struct puffs_usermount *, struct puffs_node *,
|
||||
const char *, const struct vattr *);
|
||||
struct psshfs_dir *direnter(struct puffs_node *, const char *);
|
||||
void nukenode(struct puffs_node *, const char *, int);
|
||||
void doreclaim(struct puffs_node *);
|
||||
int getpathattr(struct puffs_usermount *, const char *, struct vattr *);
|
||||
int getnodeattr(struct puffs_usermount *, struct puffs_node *, const char *);
|
||||
|
||||
void closehandles(struct puffs_usermount *, struct psshfs_node *, int);
|
||||
void lazyopen_rresp(struct puffs_usermount *, struct puffs_framebuf *,
|
||||
void *, int);
|
||||
void lazyopen_wresp(struct puffs_usermount *, struct puffs_framebuf *,
|
||||
void *, int);
|
||||
|
||||
#endif /* PSSHFS_H_ */
|
||||
122
usr.sbin/puffs/mount_psshfs/sftp_proto.h
Normal file
122
usr.sbin/puffs/mount_psshfs/sftp_proto.h
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/* $NetBSD: sftp_proto.h,v 1.2 2007/06/06 01:55:03 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* copypaste from draft-ietf-secsh-filexfer-03.txt
|
||||
*
|
||||
* XXX: we only implement protocol version 03. We should *definitely*
|
||||
* support a later version, since it maps to the vnode interface much
|
||||
* better. the problem is that most sftp servers only implement v3
|
||||
* and I don't currently have the energy to deal with compat-fuddling
|
||||
* in the code.
|
||||
*/
|
||||
|
||||
#ifndef PSSHFS_SFTPPROTO_H_
|
||||
#define PSSHFS_SFTPPROTO_H_
|
||||
|
||||
/* 3 General Packet Format */
|
||||
|
||||
#define SSH_FXP_INIT 1
|
||||
#define SSH_FXP_VERSION 2
|
||||
#define SSH_FXP_OPEN 3
|
||||
#define SSH_FXP_CLOSE 4
|
||||
#define SSH_FXP_READ 5
|
||||
#define SSH_FXP_WRITE 6
|
||||
#define SSH_FXP_LSTAT 7
|
||||
#define SSH_FXP_FSTAT 8
|
||||
#define SSH_FXP_SETSTAT 9
|
||||
#define SSH_FXP_FSETSTAT 10
|
||||
#define SSH_FXP_OPENDIR 11
|
||||
#define SSH_FXP_READDIR 12
|
||||
#define SSH_FXP_REMOVE 13
|
||||
#define SSH_FXP_MKDIR 14
|
||||
#define SSH_FXP_RMDIR 15
|
||||
#define SSH_FXP_REALPATH 16
|
||||
#define SSH_FXP_STAT 17
|
||||
#define SSH_FXP_RENAME 18
|
||||
#define SSH_FXP_READLINK 19
|
||||
#define SSH_FXP_SYMLINK 20
|
||||
|
||||
#define SSH_FXP_STATUS 101
|
||||
#define SSH_FXP_HANDLE 102
|
||||
#define SSH_FXP_DATA 103
|
||||
#define SSH_FXP_NAME 104
|
||||
#define SSH_FXP_ATTRS 105
|
||||
|
||||
#define SSH_FXP_EXTENDED 200
|
||||
#define SSH_FXP_EXTENDED_REPLY 201
|
||||
|
||||
/* 5.1 Flags */
|
||||
|
||||
/* XXX: UIDGID is obsoleted *AND NOT VALID* for version 3 of the protocol */
|
||||
#define SSH_FILEXFER_ATTR_SIZE 0x00000001
|
||||
#define SSH_FILEXFER_ATTR_UIDGID 0x00000002
|
||||
#define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
|
||||
#define SSH_FILEXFER_ATTR_ACCESSTIME 0x00000008
|
||||
#define SSH_FILEXFER_ATTR_CREATETIME 0x00000010
|
||||
#define SSH_FILEXFER_ATTR_MODIFYTIME 0x00000020
|
||||
#define SSH_FILEXFER_ATTR_ACL 0x00000040
|
||||
#define SSH_FILEXFER_ATTR_OWNERGROUP 0x00000080
|
||||
#define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
|
||||
|
||||
/* 5.2 Type */
|
||||
|
||||
#define SSH_FILEXFER_TYPE_REGULAR 1
|
||||
#define SSH_FILEXFER_TYPE_DIRECTORY 2
|
||||
#define SSH_FILEXFER_TYPE_SYMLINK 3
|
||||
#define SSH_FILEXFER_TYPE_SPECIAL 4
|
||||
#define SSH_FILEXFER_TYPE_UNKNOWN 5
|
||||
|
||||
|
||||
/* 6.3 Opening, Creating, and Closing Files */
|
||||
|
||||
#define SSH_FXF_READ 0x00000001
|
||||
#define SSH_FXF_WRITE 0x00000002
|
||||
#define SSH_FXF_APPEND 0x00000004
|
||||
#define SSH_FXF_CREAT 0x00000008
|
||||
#define SSH_FXF_TRUNC 0x00000010
|
||||
#define SSH_FXF_EXCL 0x00000020
|
||||
#define SSH_FXF_TEXT 0x00000040
|
||||
|
||||
|
||||
/* 7. Responses from the Server to the Client */
|
||||
|
||||
#define SSH_FX_OK 0
|
||||
#define SSH_FX_EOF 1
|
||||
#define SSH_FX_NO_SUCH_FILE 2
|
||||
#define SSH_FX_PERMISSION_DENIED 3
|
||||
#define SSH_FX_FAILURE 4
|
||||
#define SSH_FX_BAD_MESSAGE 5
|
||||
#define SSH_FX_NO_CONNECTION 6
|
||||
#define SSH_FX_CONNECTION_LOST 7
|
||||
#define SSH_FX_OP_UNSUPPORTED 8
|
||||
#define SSH_FX_INVALID_HANDLE 9
|
||||
#define SSH_FX_NO_SUCH_PATH 10
|
||||
#define SSH_FX_FILE_ALREADY_EXISTS 11
|
||||
#define SSH_FX_WRITE_PROTECT 12
|
||||
|
||||
#endif /* PSSHFS_SFTPPROTO_H_ */
|
||||
548
usr.sbin/puffs/mount_psshfs/subr.c
Normal file
548
usr.sbin/puffs/mount_psshfs/subr.c
Normal file
|
|
@ -0,0 +1,548 @@
|
|||
/* $NetBSD: subr.c,v 1.51 2012/11/04 22:46:08 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: subr.c,v 1.51 2012/11/04 22:46:08 christos Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include "psshfs.h"
|
||||
#include "sftp_proto.h"
|
||||
|
||||
static void
|
||||
freedircache(struct psshfs_dir *base, size_t count)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
free(base[i].entryname);
|
||||
base[i].entryname = NULL;
|
||||
}
|
||||
|
||||
free(base);
|
||||
}
|
||||
|
||||
#define ENTRYCHUNK 16
|
||||
static void
|
||||
allocdirs(struct psshfs_node *psn)
|
||||
{
|
||||
size_t oldtot = psn->denttot;
|
||||
|
||||
psn->denttot += ENTRYCHUNK;
|
||||
psn->dir = erealloc(psn->dir,
|
||||
psn->denttot * sizeof(struct psshfs_dir));
|
||||
memset(psn->dir + oldtot, 0, ENTRYCHUNK * sizeof(struct psshfs_dir));
|
||||
}
|
||||
|
||||
static void
|
||||
setpnva(struct puffs_usermount *pu, struct puffs_node *pn,
|
||||
const struct vattr *vap)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
struct vattr modva;
|
||||
|
||||
/*
|
||||
* Check if the file was modified from below us.
|
||||
* If so, invalidate page cache. This is the only
|
||||
* sensible place we can do this in.
|
||||
*/
|
||||
if (pn->pn_va.va_mtime.tv_sec != PUFFS_VNOVAL)
|
||||
if (pn->pn_va.va_mtime.tv_sec != vap->va_mtime.tv_sec
|
||||
&& pn->pn_va.va_type == VREG)
|
||||
puffs_inval_pagecache_node(pu, pn);
|
||||
|
||||
modva = *vap;
|
||||
if (pctx->domangleuid && modva.va_uid == pctx->mangleuid)
|
||||
modva.va_uid = pctx->myuid;
|
||||
if (pctx->domanglegid && modva.va_gid == pctx->manglegid)
|
||||
modva.va_gid = pctx->mygid;
|
||||
|
||||
puffs_setvattr(&pn->pn_va, &modva);
|
||||
psn->attrread = time(NULL);
|
||||
}
|
||||
|
||||
struct psshfs_dir *
|
||||
lookup(struct psshfs_dir *bdir, size_t ndir, const char *name)
|
||||
{
|
||||
struct psshfs_dir *test;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ndir; i++) {
|
||||
test = &bdir[i];
|
||||
if (test->valid != 1)
|
||||
continue;
|
||||
if (strcmp(test->entryname, name) == 0)
|
||||
return test;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct psshfs_dir *
|
||||
lookup_by_entry(struct psshfs_dir *bdir, size_t ndir, struct puffs_node *entry)
|
||||
{
|
||||
struct psshfs_dir *test;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ndir; i++) {
|
||||
test = &bdir[i];
|
||||
if (test->valid != 1)
|
||||
continue;
|
||||
if (test->entry == entry)
|
||||
return test;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
closehandles(struct puffs_usermount *pu, struct psshfs_node *psn, int which)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
struct puffs_framebuf *pb1, *pb2;
|
||||
uint32_t reqid;
|
||||
|
||||
if (psn->fhand_r && (which & HANDLE_READ)) {
|
||||
assert(psn->lazyopen_r == NULL);
|
||||
|
||||
pb1 = psbuf_makeout();
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_req_data(pb1, SSH_FXP_CLOSE, reqid,
|
||||
psn->fhand_r, psn->fhand_r_len);
|
||||
puffs_framev_enqueue_justsend(pu, pctx->sshfd_data, pb1, 1, 0);
|
||||
free(psn->fhand_r);
|
||||
psn->fhand_r = NULL;
|
||||
}
|
||||
|
||||
if (psn->fhand_w && (which & HANDLE_WRITE)) {
|
||||
assert(psn->lazyopen_w == NULL);
|
||||
|
||||
pb2 = psbuf_makeout();
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_req_data(pb2, SSH_FXP_CLOSE, reqid,
|
||||
psn->fhand_w, psn->fhand_w_len);
|
||||
puffs_framev_enqueue_justsend(pu, pctx->sshfd_data, pb2, 1, 0);
|
||||
free(psn->fhand_w);
|
||||
psn->fhand_w = NULL;
|
||||
}
|
||||
|
||||
psn->stat |= PSN_HANDLECLOSE;
|
||||
}
|
||||
|
||||
void
|
||||
lazyopen_rresp(struct puffs_usermount *pu, struct puffs_framebuf *pb,
|
||||
void *arg, int error)
|
||||
{
|
||||
struct psshfs_node *psn = arg;
|
||||
|
||||
/* XXX: this is not enough */
|
||||
if (psn->stat & PSN_RECLAIMED) {
|
||||
error = ENOENT;
|
||||
goto moreout;
|
||||
}
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = psbuf_expect_handle(pb, &psn->fhand_r, &psn->fhand_r_len);
|
||||
|
||||
out:
|
||||
psn->lazyopen_err_r = error;
|
||||
psn->lazyopen_r = NULL;
|
||||
if (error)
|
||||
psn->stat &= ~PSN_DOLAZY_R;
|
||||
if (psn->stat & PSN_HANDLECLOSE && (psn->stat & PSN_LAZYWAIT_R) == 0)
|
||||
closehandles(pu, psn, HANDLE_READ);
|
||||
moreout:
|
||||
puffs_framebuf_destroy(pb);
|
||||
}
|
||||
|
||||
void
|
||||
lazyopen_wresp(struct puffs_usermount *pu, struct puffs_framebuf *pb,
|
||||
void *arg, int error)
|
||||
{
|
||||
struct psshfs_node *psn = arg;
|
||||
|
||||
/* XXX: this is not enough */
|
||||
if (psn->stat & PSN_RECLAIMED) {
|
||||
error = ENOENT;
|
||||
goto moreout;
|
||||
}
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = psbuf_expect_handle(pb, &psn->fhand_w, &psn->fhand_w_len);
|
||||
|
||||
out:
|
||||
psn->lazyopen_err_w = error;
|
||||
psn->lazyopen_w = NULL;
|
||||
if (error)
|
||||
psn->stat &= ~PSN_DOLAZY_W;
|
||||
if (psn->stat & PSN_HANDLECLOSE && (psn->stat & PSN_LAZYWAIT_W) == 0)
|
||||
closehandles(pu, psn, HANDLE_WRITE);
|
||||
moreout:
|
||||
puffs_framebuf_destroy(pb);
|
||||
}
|
||||
|
||||
struct readdirattr {
|
||||
struct psshfs_node *psn;
|
||||
int idx;
|
||||
char entryname[MAXPATHLEN+1];
|
||||
};
|
||||
|
||||
int
|
||||
getpathattr(struct puffs_usermount *pu, const char *path, struct vattr *vap)
|
||||
{
|
||||
PSSHFSAUTOVAR(pu);
|
||||
|
||||
psbuf_req_str(pb, SSH_FXP_LSTAT, reqid, path);
|
||||
GETRESPONSE(pb, pctx->sshfd);
|
||||
|
||||
rv = psbuf_expect_attrs(pb, vap);
|
||||
|
||||
out:
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
int
|
||||
getnodeattr(struct puffs_usermount *pu, struct puffs_node *pn, const char *path)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
struct vattr va;
|
||||
int rv;
|
||||
|
||||
if (!psn->attrread || REFRESHTIMEOUT(pctx, time(NULL)-psn->attrread)) {
|
||||
rv = getpathattr(pu, path ? path : PNPATH(pn), &va);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
setpnva(pu, pn, &va);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sftp_readdir(struct puffs_usermount *pu, struct psshfs_ctx *pctx,
|
||||
struct puffs_node *pn)
|
||||
{
|
||||
struct puffs_cc *pcc = puffs_cc_getcc(pu);
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
struct psshfs_dir *olddir, *testd;
|
||||
struct puffs_framebuf *pb;
|
||||
uint32_t reqid = NEXTREQ(pctx);
|
||||
uint32_t count, dhandlen;
|
||||
char *dhand = NULL;
|
||||
size_t nent;
|
||||
char *longname = NULL;
|
||||
size_t idx;
|
||||
int rv;
|
||||
|
||||
assert(pn->pn_va.va_type == VDIR);
|
||||
idx = 0;
|
||||
olddir = psn->dir;
|
||||
nent = psn->dentnext;
|
||||
|
||||
if (psn->dir && psn->dentread
|
||||
&& !REFRESHTIMEOUT(pctx, time(NULL) - psn->dentread))
|
||||
return 0;
|
||||
|
||||
if (psn->dentread) {
|
||||
if ((rv = puffs_inval_namecache_dir(pu, pn)))
|
||||
warn("readdir: dcache inval fail %p", pn);
|
||||
}
|
||||
|
||||
pb = psbuf_makeout();
|
||||
psbuf_req_str(pb, SSH_FXP_OPENDIR, reqid, PNPATH(pn));
|
||||
if (puffs_framev_enqueue_cc(pcc, pctx->sshfd, pb, 0) == -1) {
|
||||
rv = errno;
|
||||
goto wayout;
|
||||
}
|
||||
rv = psbuf_expect_handle(pb, &dhand, &dhandlen);
|
||||
if (rv)
|
||||
goto wayout;
|
||||
|
||||
/*
|
||||
* Well, the following is O(n^2), so feel free to improve if it
|
||||
* gets too taxing on your system.
|
||||
*/
|
||||
|
||||
/*
|
||||
* note: for the "getattr in batch" to work, this must be before
|
||||
* the attribute-getting. Otherwise times for first entries in
|
||||
* large directories might expire before the directory itself and
|
||||
* result in one-by-one attribute fetching.
|
||||
*/
|
||||
psn->dentread = time(NULL);
|
||||
|
||||
psn->dentnext = 0;
|
||||
psn->denttot = 0;
|
||||
psn->dir = NULL;
|
||||
|
||||
for (;;) {
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_recycleout(pb);
|
||||
psbuf_req_data(pb, SSH_FXP_READDIR, reqid, dhand, dhandlen);
|
||||
GETRESPONSE(pb, pctx->sshfd);
|
||||
|
||||
/* check for EOF */
|
||||
if (psbuf_get_type(pb) == SSH_FXP_STATUS) {
|
||||
rv = psbuf_expect_status(pb);
|
||||
goto out;
|
||||
}
|
||||
rv = psbuf_expect_name(pb, &count);
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
for (; count--; idx++) {
|
||||
if (idx == psn->denttot)
|
||||
allocdirs(psn);
|
||||
if ((rv = psbuf_get_str(pb,
|
||||
&psn->dir[idx].entryname, NULL)))
|
||||
goto out;
|
||||
if ((rv = psbuf_get_str(pb, &longname, NULL)) != 0)
|
||||
goto out;
|
||||
if ((rv = psbuf_get_vattr(pb, &psn->dir[idx].va)) != 0)
|
||||
goto out;
|
||||
if (sscanf(longname, "%*s%d",
|
||||
&psn->dir[idx].va.va_nlink) != 1) {
|
||||
rv = EPROTO;
|
||||
goto out;
|
||||
}
|
||||
free(longname);
|
||||
longname = NULL;
|
||||
|
||||
/*
|
||||
* In case of DOT, copy the attributes (mostly
|
||||
* because we want the link count for the root dir).
|
||||
*/
|
||||
if (strcmp(psn->dir[idx].entryname, ".") == 0) {
|
||||
setpnva(pu, pn, &psn->dir[idx].va);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we already have a psshfs_dir for the
|
||||
* name we are processing. If so, use the old one.
|
||||
* If not, create a new one
|
||||
*/
|
||||
testd = lookup(olddir, nent, psn->dir[idx].entryname);
|
||||
if (testd) {
|
||||
psn->dir[idx].entry = testd->entry;
|
||||
/*
|
||||
* Has entry. Update attributes to what
|
||||
* we just got from the server.
|
||||
*/
|
||||
if (testd->entry) {
|
||||
setpnva(pu, testd->entry,
|
||||
&psn->dir[idx].va);
|
||||
psn->dir[idx].va.va_fileid
|
||||
= testd->entry->pn_va.va_fileid;
|
||||
|
||||
/*
|
||||
* No entry. This can happen in two cases:
|
||||
* 1) the file was created "behind our back"
|
||||
* on the server
|
||||
* 2) we do two readdirs before we instantiate
|
||||
* the node (or run with -t 0).
|
||||
*
|
||||
* Cache attributes from the server in
|
||||
* case we want to instantiate this node
|
||||
* soon. Also preserve the old inode number
|
||||
* which was given when the dirent was created.
|
||||
*/
|
||||
} else {
|
||||
psn->dir[idx].va.va_fileid
|
||||
= testd->va.va_fileid;
|
||||
testd->va = psn->dir[idx].va;
|
||||
}
|
||||
|
||||
/* No previous entry? Initialize this one. */
|
||||
} else {
|
||||
psn->dir[idx].entry = NULL;
|
||||
psn->dir[idx].va.va_fileid = pctx->nextino++;
|
||||
}
|
||||
psn->dir[idx].attrread = psn->dentread;
|
||||
psn->dir[idx].valid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
/* XXX: rv */
|
||||
psn->dentnext = idx;
|
||||
freedircache(olddir, nent);
|
||||
|
||||
reqid = NEXTREQ(pctx);
|
||||
psbuf_recycleout(pb);
|
||||
psbuf_req_data(pb, SSH_FXP_CLOSE, reqid, dhand, dhandlen);
|
||||
puffs_framev_enqueue_justsend(pu, pctx->sshfd, pb, 1, 0);
|
||||
free(dhand);
|
||||
free(longname);
|
||||
|
||||
return rv;
|
||||
|
||||
wayout:
|
||||
free(dhand);
|
||||
PSSHFSRETURN(rv);
|
||||
}
|
||||
|
||||
struct puffs_node *
|
||||
makenode(struct puffs_usermount *pu, struct puffs_node *parent,
|
||||
const struct psshfs_dir *pd, const struct vattr *vap)
|
||||
{
|
||||
struct psshfs_node *psn_parent = parent->pn_data;
|
||||
struct psshfs_node *psn;
|
||||
struct puffs_node *pn;
|
||||
|
||||
psn = emalloc(sizeof(struct psshfs_node));
|
||||
memset(psn, 0, sizeof(struct psshfs_node));
|
||||
|
||||
pn = puffs_pn_new(pu, psn);
|
||||
if (!pn) {
|
||||
free(psn);
|
||||
return NULL;
|
||||
}
|
||||
setpnva(pu, pn, &pd->va);
|
||||
setpnva(pu, pn, vap);
|
||||
psn->attrread = pd->attrread;
|
||||
|
||||
psn->parent = parent;
|
||||
psn_parent->childcount++;
|
||||
|
||||
TAILQ_INIT(&psn->pw);
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
struct puffs_node *
|
||||
allocnode(struct puffs_usermount *pu, struct puffs_node *parent,
|
||||
const char *entryname, const struct vattr *vap)
|
||||
{
|
||||
struct psshfs_ctx *pctx = puffs_getspecific(pu);
|
||||
struct psshfs_dir *pd;
|
||||
struct puffs_node *pn;
|
||||
|
||||
pd = direnter(parent, entryname);
|
||||
|
||||
pd->va.va_fileid = pctx->nextino++;
|
||||
if (vap->va_type == VDIR) {
|
||||
pd->va.va_nlink = 2;
|
||||
parent->pn_va.va_nlink++;
|
||||
} else {
|
||||
pd->va.va_nlink = 1;
|
||||
}
|
||||
|
||||
pn = makenode(pu, parent, pd, vap);
|
||||
if (pn) {
|
||||
pd->va.va_fileid = pn->pn_va.va_fileid;
|
||||
pd->entry = pn;
|
||||
}
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
struct psshfs_dir *
|
||||
direnter(struct puffs_node *parent, const char *entryname)
|
||||
{
|
||||
struct psshfs_node *psn_parent = parent->pn_data;
|
||||
struct psshfs_dir *pd;
|
||||
int i;
|
||||
|
||||
/* create directory entry */
|
||||
if (psn_parent->denttot == psn_parent->dentnext)
|
||||
allocdirs(psn_parent);
|
||||
|
||||
i = psn_parent->dentnext;
|
||||
pd = &psn_parent->dir[i];
|
||||
pd->entryname = estrdup(entryname);
|
||||
pd->valid = 1;
|
||||
pd->attrread = 0;
|
||||
puffs_vattr_null(&pd->va);
|
||||
psn_parent->dentnext++;
|
||||
|
||||
return pd;
|
||||
}
|
||||
|
||||
void
|
||||
doreclaim(struct puffs_node *pn)
|
||||
{
|
||||
struct psshfs_node *psn = pn->pn_data;
|
||||
struct psshfs_node *psn_parent;
|
||||
struct psshfs_dir *dent;
|
||||
|
||||
psn_parent = psn->parent->pn_data;
|
||||
psn_parent->childcount--;
|
||||
|
||||
/*
|
||||
* Null out entry from directory. Do not treat a missing entry
|
||||
* as an invariant error, since the node might be removed from
|
||||
* under us, and we might do a readdir before the reclaim resulting
|
||||
* in no directory entry in the parent directory.
|
||||
*/
|
||||
dent = lookup_by_entry(psn_parent->dir, psn_parent->dentnext, pn);
|
||||
if (dent)
|
||||
dent->entry = NULL;
|
||||
|
||||
if (pn->pn_va.va_type == VDIR) {
|
||||
freedircache(psn->dir, psn->dentnext);
|
||||
psn->denttot = psn->dentnext = 0;
|
||||
}
|
||||
if (psn->symlink)
|
||||
free(psn->symlink);
|
||||
|
||||
puffs_pn_put(pn);
|
||||
}
|
||||
|
||||
void
|
||||
nukenode(struct puffs_node *node, const char *entryname, int reclaim)
|
||||
{
|
||||
struct psshfs_node *psn, *psn_parent;
|
||||
struct psshfs_dir *pd;
|
||||
|
||||
psn = node->pn_data;
|
||||
psn_parent = psn->parent->pn_data;
|
||||
pd = lookup(psn_parent->dir, psn_parent->dentnext, entryname);
|
||||
assert(pd != NULL);
|
||||
pd->valid = 0;
|
||||
free(pd->entryname);
|
||||
pd->entryname = NULL;
|
||||
|
||||
if (node->pn_va.va_type == VDIR)
|
||||
psn->parent->pn_va.va_nlink--;
|
||||
|
||||
if (reclaim)
|
||||
doreclaim(node);
|
||||
}
|
||||
16
usr.sbin/puffs/mount_sysctlfs/Makefile
Normal file
16
usr.sbin/puffs/mount_sysctlfs/Makefile
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# $NetBSD: Makefile,v 1.4 2010/08/06 15:04:13 pooka Exp $
|
||||
|
||||
PROG= mount_sysctlfs
|
||||
SRCS= sysctlfs.c
|
||||
|
||||
DPAPP+= ${LIBPUFFS} ${LIBUTIL}
|
||||
LDADD+= -lpuffs -lutil
|
||||
|
||||
MAN= mount_sysctlfs.8
|
||||
|
||||
.ifdef RUMP_ACTION
|
||||
CPPFLAGS+= -DRUMP_ACTION
|
||||
LDADD+= -lrump -lrumpuser -lpthread
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
63
usr.sbin/puffs/mount_sysctlfs/mount_sysctlfs.8
Normal file
63
usr.sbin/puffs/mount_sysctlfs/mount_sysctlfs.8
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
.\" $NetBSD: mount_sysctlfs.8,v 1.3 2010/04/11 21:34:18 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2007 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd April 11, 2010
|
||||
.Dt MOUNT_SYSCTLFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mount_sysctlfs
|
||||
.Nd mount sysctl namespace as a directory hierarchy
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl r
|
||||
.Op Fl o Ar mntopts
|
||||
.Ar sysctlfs
|
||||
.Ar mount_point
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program provides the
|
||||
.Xr sysctl 8
|
||||
hierarchy through the file system namespace.
|
||||
It is possible to browse the tree, query node values and modify them.
|
||||
By default, the node contents are interpreted as ASCII.
|
||||
If the
|
||||
.Fl r
|
||||
flag is given, the server uses raw mode and displays node contents as
|
||||
they are received from the kernel (binary).
|
||||
.Sh SEE ALSO
|
||||
.Xr puffs 3 ,
|
||||
.Xr puffs 4 ,
|
||||
.Xr mount 8 ,
|
||||
.Xr sysctl 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
.Sh CAVEATS
|
||||
Raw mode
|
||||
.Op Fl r
|
||||
does not currently support node modification.
|
||||
799
usr.sbin/puffs/mount_sysctlfs/sysctlfs.c
Normal file
799
usr.sbin/puffs/mount_sysctlfs/sysctlfs.c
Normal file
|
|
@ -0,0 +1,799 @@
|
|||
/* $NetBSD: sysctlfs.c,v 1.17 2012/11/04 22:47:21 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* sysctlfs: mount sysctls as a file system tree. Supports query and
|
||||
* modify of nodes in the sysctl namespace in addition to namespace
|
||||
* traversal.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: sysctlfs.c,v 1.17 2012/11/04 22:47:21 christos Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <mntopts.h>
|
||||
#include <paths.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
||||
#ifdef RUMP_ACTION
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
|
||||
#define sysctl(a,b,c,d,e,f) rump_sys___sysctl(a,b,c,d,e,f)
|
||||
#endif
|
||||
|
||||
PUFFSOP_PROTOS(sysctlfs)
|
||||
|
||||
struct sfsnode {
|
||||
int sysctl_flags;
|
||||
ino_t myid;
|
||||
};
|
||||
|
||||
#define SFSPATH_DOTDOT 0
|
||||
#define SFSPATH_NORMAL 1
|
||||
|
||||
#define N_HIERARCHY 10
|
||||
typedef int SfsName[N_HIERARCHY];
|
||||
|
||||
struct sfsfid {
|
||||
int len;
|
||||
SfsName path;
|
||||
};
|
||||
|
||||
static struct sfsnode rn;
|
||||
static SfsName sname_root;
|
||||
static struct timespec fstime;
|
||||
|
||||
static ino_t nextid = 3;
|
||||
static mode_t fileperms;
|
||||
static uid_t fileuid;
|
||||
static gid_t filegid;
|
||||
|
||||
static int rflag;
|
||||
|
||||
#define ISADIR(a) ((SYSCTL_TYPE(a->sysctl_flags) == CTLTYPE_NODE))
|
||||
#define SFS_MAXFILE 32768
|
||||
#define SFS_NODEPERDIR 128
|
||||
|
||||
static int sysctlfs_domount(struct puffs_usermount *);
|
||||
|
||||
/*
|
||||
* build paths. doesn't support rename (but neither does the fs)
|
||||
*/
|
||||
static int
|
||||
sysctlfs_pathbuild(struct puffs_usermount *pu,
|
||||
const struct puffs_pathobj *parent, const struct puffs_pathobj *comp,
|
||||
size_t offset, struct puffs_pathobj *res)
|
||||
{
|
||||
SfsName *sname;
|
||||
size_t clen;
|
||||
|
||||
assert(parent->po_len < N_HIERARCHY); /* code uses +1 */
|
||||
|
||||
sname = malloc(sizeof(SfsName));
|
||||
assert(sname != NULL);
|
||||
|
||||
clen = parent->po_len;
|
||||
if (comp->po_len == SFSPATH_DOTDOT) {
|
||||
assert(clen != 0);
|
||||
clen--;
|
||||
}
|
||||
|
||||
memcpy(sname, parent->po_path, clen * sizeof(int));
|
||||
|
||||
res->po_path = sname;
|
||||
res->po_len = clen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sysctlfs_pathtransform(struct puffs_usermount *pu,
|
||||
const struct puffs_pathobj *p, const struct puffs_cn *pcn,
|
||||
struct puffs_pathobj *res)
|
||||
{
|
||||
|
||||
res->po_path = NULL;
|
||||
/*
|
||||
* XXX: overload. prevents us from doing rename, but the fs
|
||||
* (and sysctl(3)) doesn't support it, so no biggie
|
||||
*/
|
||||
if (PCNISDOTDOT(pcn)) {
|
||||
res->po_len = SFSPATH_DOTDOT;
|
||||
}else {
|
||||
res->po_len = SFSPATH_NORMAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sysctlfs_pathcmp(struct puffs_usermount *pu, struct puffs_pathobj *po1,
|
||||
struct puffs_pathobj *po2, size_t clen, int checkprefix)
|
||||
{
|
||||
|
||||
if (memcmp(po1->po_path, po2->po_path, clen * sizeof(int)) == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
sysctlfs_pathfree(struct puffs_usermount *pu, struct puffs_pathobj *po)
|
||||
{
|
||||
|
||||
free(po->po_path);
|
||||
}
|
||||
|
||||
static struct puffs_node *
|
||||
getnode(struct puffs_usermount *pu, struct puffs_pathobj *po, int nodetype)
|
||||
{
|
||||
struct sysctlnode sn[SFS_NODEPERDIR];
|
||||
struct sysctlnode qnode;
|
||||
struct puffs_node *pn;
|
||||
struct sfsnode *sfs;
|
||||
SfsName myname, *sname;
|
||||
size_t sl, i;
|
||||
|
||||
/*
|
||||
* Check if we need to create a new in-memory node or if we
|
||||
* already have one for this path. Shortcut for the rootnode.
|
||||
* Also, memcmp against zero-length would be quite true always.
|
||||
*/
|
||||
if (po->po_len == 0)
|
||||
pn = puffs_getroot(pu);
|
||||
else
|
||||
pn = puffs_pn_nodewalk(pu, puffs_path_walkcmp, po);
|
||||
|
||||
if (pn == NULL) {
|
||||
/*
|
||||
* don't know nodetype? query...
|
||||
*
|
||||
* XXX1: nothing really guarantees 0 is an invalid nodetype
|
||||
* XXX2: is there really no easier way of doing this? we
|
||||
* know the whole mib path
|
||||
*/
|
||||
if (!nodetype) {
|
||||
sname = po->po_path;
|
||||
memcpy(myname, po->po_path, po->po_len * sizeof(int));
|
||||
|
||||
memset(&qnode, 0, sizeof(qnode));
|
||||
qnode.sysctl_flags = SYSCTL_VERSION;
|
||||
myname[po->po_len-1] = CTL_QUERY;
|
||||
|
||||
sl = sizeof(sn);
|
||||
if (sysctl(myname, po->po_len, sn, &sl,
|
||||
&qnode, sizeof(qnode)) == -1)
|
||||
abort();
|
||||
|
||||
for (i = 0; i < sl / sizeof(struct sysctlnode); i++) {
|
||||
if (sn[i].sysctl_num==(*sname)[po->po_len-1]) {
|
||||
nodetype = sn[i].sysctl_flags;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nodetype)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sfs = emalloc(sizeof(struct sfsnode));
|
||||
sfs->sysctl_flags = nodetype;
|
||||
sfs->myid = nextid++;
|
||||
|
||||
pn = puffs_pn_new(pu, sfs);
|
||||
assert(pn);
|
||||
}
|
||||
|
||||
return pn;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct puffs_usermount *pu;
|
||||
struct puffs_ops *pops;
|
||||
mntoptparse_t mp;
|
||||
int mntflags, pflags;
|
||||
int detach;
|
||||
int ch;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
if (argc < 2)
|
||||
errx(1, "usage: %s sysctlfs [-o mntopts] mountpath",
|
||||
getprogname());
|
||||
|
||||
mntflags = pflags = 0;
|
||||
detach = 1;
|
||||
while ((ch = getopt(argc, argv, "o:rs")) != -1) {
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags);
|
||||
if (mp == NULL)
|
||||
err(1, "getmntopts");
|
||||
freemntopts(mp);
|
||||
break;
|
||||
case 'r':
|
||||
rflag = 1;
|
||||
break;
|
||||
case 's':
|
||||
detach = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
pflags |= PUFFS_FLAG_BUILDPATH | PUFFS_KFLAG_NOCACHE;
|
||||
|
||||
if (pflags & PUFFS_FLAG_OPDUMP)
|
||||
detach = 0;
|
||||
|
||||
if (argc != 2)
|
||||
errx(1, "usage: %s [-o mntopts] mountpath", getprogname());
|
||||
|
||||
PUFFSOP_INIT(pops);
|
||||
|
||||
PUFFSOP_SETFSNOP(pops, unmount);
|
||||
PUFFSOP_SETFSNOP(pops, sync);
|
||||
PUFFSOP_SETFSNOP(pops, statvfs);
|
||||
PUFFSOP_SET(pops, sysctlfs, fs, nodetofh);
|
||||
PUFFSOP_SET(pops, sysctlfs, fs, fhtonode);
|
||||
|
||||
PUFFSOP_SET(pops, sysctlfs, node, lookup);
|
||||
PUFFSOP_SET(pops, sysctlfs, node, getattr);
|
||||
PUFFSOP_SET(pops, sysctlfs, node, setattr);
|
||||
PUFFSOP_SET(pops, sysctlfs, node, readdir);
|
||||
PUFFSOP_SET(pops, sysctlfs, node, read);
|
||||
PUFFSOP_SET(pops, sysctlfs, node, write);
|
||||
PUFFSOP_SET(pops, puffs_genfs, node, reclaim);
|
||||
|
||||
pu = puffs_init(pops, _PATH_PUFFS, "sysctlfs", NULL, pflags);
|
||||
if (pu == NULL)
|
||||
err(1, "puffs_init");
|
||||
|
||||
puffs_set_pathbuild(pu, sysctlfs_pathbuild);
|
||||
puffs_set_pathtransform(pu, sysctlfs_pathtransform);
|
||||
puffs_set_pathcmp(pu, sysctlfs_pathcmp);
|
||||
puffs_set_pathfree(pu, sysctlfs_pathfree);
|
||||
|
||||
puffs_setfhsize(pu, sizeof(struct sfsfid), PUFFS_FHFLAG_NFSV3);
|
||||
|
||||
if (sysctlfs_domount(pu) != 0)
|
||||
errx(1, "domount");
|
||||
|
||||
if (detach)
|
||||
if (puffs_daemon(pu, 1, 1) == -1)
|
||||
err(1, "puffs_daemon");
|
||||
|
||||
#ifdef RUMP_ACTION
|
||||
{
|
||||
extern int puffs_fakecc;
|
||||
puffs_fakecc = 1;
|
||||
rump_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (puffs_mount(pu, argv[1], mntflags, puffs_getroot(pu)) == -1)
|
||||
err(1, "puffs_mount");
|
||||
if (puffs_mainloop(pu) == -1)
|
||||
err(1, "mainloop");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sysctlfs_domount(struct puffs_usermount *pu)
|
||||
{
|
||||
struct puffs_pathobj *po_root;
|
||||
struct puffs_node *pn_root;
|
||||
struct timeval tv_now;
|
||||
|
||||
rn.myid = 2;
|
||||
rn.sysctl_flags = CTLTYPE_NODE;
|
||||
|
||||
gettimeofday(&tv_now, NULL);
|
||||
TIMEVAL_TO_TIMESPEC(&tv_now, &fstime);
|
||||
|
||||
pn_root = puffs_pn_new(pu, &rn);
|
||||
assert(pn_root != NULL);
|
||||
puffs_setroot(pu, pn_root);
|
||||
|
||||
po_root = puffs_getrootpathobj(pu);
|
||||
po_root->po_path = &sname_root;
|
||||
po_root->po_len = 0;
|
||||
|
||||
fileuid = geteuid();
|
||||
filegid = getegid();
|
||||
|
||||
if (fileuid == 0)
|
||||
fileperms = 0755;
|
||||
else
|
||||
fileperms = 0555;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sysctlfs_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
|
||||
struct puffs_newinfo *pni)
|
||||
{
|
||||
struct puffs_pathobj po;
|
||||
struct puffs_node *pn;
|
||||
struct sfsnode *sfs;
|
||||
struct sfsfid *sfid;
|
||||
|
||||
sfid = fid;
|
||||
|
||||
po.po_len = sfid->len;
|
||||
po.po_path = &sfid->path;
|
||||
|
||||
pn = getnode(pu, &po, 0);
|
||||
if (pn == NULL)
|
||||
return EINVAL;
|
||||
sfs = pn->pn_data;
|
||||
|
||||
puffs_newinfo_setcookie(pni, pn);
|
||||
if (ISADIR(sfs))
|
||||
puffs_newinfo_setvtype(pni, VDIR);
|
||||
else
|
||||
puffs_newinfo_setvtype(pni, VREG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sysctlfs_fs_nodetofh(struct puffs_usermount *pu, void *cookie,
|
||||
void *fid, size_t *fidsize)
|
||||
{
|
||||
struct puffs_node *pn = cookie;
|
||||
struct sfsfid *sfid;
|
||||
|
||||
sfid = fid;
|
||||
sfid->len = PNPLEN(pn);
|
||||
memcpy(&sfid->path, PNPATH(pn), sfid->len * sizeof(int));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
getnodedata(struct sfsnode *sfs, struct puffs_pathobj *po,
|
||||
char *buf, size_t *bufsize)
|
||||
{
|
||||
size_t sz;
|
||||
int error = 0;
|
||||
|
||||
assert(!ISADIR(sfs));
|
||||
|
||||
memset(buf, 0, *bufsize);
|
||||
switch (SYSCTL_TYPE(sfs->sysctl_flags)) {
|
||||
case CTLTYPE_BOOL: {
|
||||
bool b;
|
||||
sz = sizeof(bool);
|
||||
assert(sz <= *bufsize);
|
||||
if (sysctl(po->po_path, po->po_len, &b, &sz, NULL, 0) == -1) {
|
||||
error = errno;
|
||||
break;
|
||||
}
|
||||
if (rflag)
|
||||
memcpy(buf, &b, sz);
|
||||
else
|
||||
snprintf(buf, *bufsize, "%s", b ? "true" : "false");
|
||||
break;
|
||||
}
|
||||
case CTLTYPE_INT: {
|
||||
int i;
|
||||
sz = sizeof(int);
|
||||
assert(sz <= *bufsize);
|
||||
if (sysctl(po->po_path, po->po_len, &i, &sz, NULL, 0) == -1) {
|
||||
error = errno;
|
||||
break;
|
||||
}
|
||||
if (rflag)
|
||||
memcpy(buf, &i, sz);
|
||||
else
|
||||
snprintf(buf, *bufsize, "%d", i);
|
||||
break;
|
||||
}
|
||||
case CTLTYPE_QUAD: {
|
||||
quad_t q;
|
||||
sz = sizeof(q);
|
||||
assert(sz <= *bufsize);
|
||||
if (sysctl(po->po_path, po->po_len, &q, &sz, NULL, 0) == -1) {
|
||||
error = errno;
|
||||
break;
|
||||
}
|
||||
if (rflag)
|
||||
memcpy(buf, &q, sz);
|
||||
else
|
||||
snprintf(buf, *bufsize, "%" PRId64, q);
|
||||
break;
|
||||
}
|
||||
case CTLTYPE_STRUCT: {
|
||||
uint8_t snode[SFS_MAXFILE/2-1];
|
||||
unsigned i;
|
||||
|
||||
sz = sizeof(snode);
|
||||
assert(sz <= *bufsize);
|
||||
if (sysctl(po->po_path, po->po_len, snode, &sz, NULL, 0) == -1){
|
||||
error = errno;
|
||||
break;
|
||||
}
|
||||
if (rflag) {
|
||||
memcpy(buf, &snode, sz);
|
||||
} else {
|
||||
for (i = 0; i < sz && 2*i < *bufsize; i++) {
|
||||
sprintf(&buf[2*i], "%02x", snode[i]);
|
||||
}
|
||||
buf[2*i] = '\0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CTLTYPE_STRING: {
|
||||
sz = *bufsize;
|
||||
assert(sz <= *bufsize);
|
||||
if (sysctl(po->po_path, po->po_len, buf, &sz, NULL, 0) == -1) {
|
||||
error = errno;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
snprintf(buf, *bufsize, "invalid sysctl CTLTYPE %d",
|
||||
SYSCTL_TYPE(sfs->sysctl_flags));
|
||||
break;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
*bufsize = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rflag)
|
||||
*bufsize = sz;
|
||||
else
|
||||
*bufsize = strlen(buf);
|
||||
}
|
||||
|
||||
static int
|
||||
getlinks(struct sfsnode *sfs, struct puffs_pathobj *po)
|
||||
{
|
||||
struct sysctlnode sn[SFS_NODEPERDIR];
|
||||
struct sysctlnode qnode;
|
||||
SfsName *sname;
|
||||
size_t sl;
|
||||
|
||||
if (!ISADIR(sfs))
|
||||
return 1;
|
||||
|
||||
memset(&qnode, 0, sizeof(qnode));
|
||||
sl = sizeof(sn);
|
||||
qnode.sysctl_flags = SYSCTL_VERSION;
|
||||
sname = po->po_path;
|
||||
(*sname)[po->po_len] = CTL_QUERY;
|
||||
|
||||
if (sysctl(*sname, po->po_len + 1, sn, &sl,
|
||||
&qnode, sizeof(qnode)) == -1)
|
||||
return 0;
|
||||
|
||||
return (sl / sizeof(sn[0])) + 2;
|
||||
}
|
||||
|
||||
static int
|
||||
getsize(struct sfsnode *sfs, struct puffs_pathobj *po)
|
||||
{
|
||||
char buf[SFS_MAXFILE];
|
||||
size_t sz = sizeof(buf);
|
||||
|
||||
if (ISADIR(sfs))
|
||||
return getlinks(sfs, po) * 16; /* totally arbitrary */
|
||||
|
||||
getnodedata(sfs, po, buf, &sz);
|
||||
if (rflag)
|
||||
return sz;
|
||||
else
|
||||
return sz + 1; /* for \n, not \0 */
|
||||
}
|
||||
|
||||
int
|
||||
sysctlfs_node_lookup(struct puffs_usermount *pu, void *opc,
|
||||
struct puffs_newinfo *pni, const struct puffs_cn *pcn)
|
||||
{
|
||||
struct puffs_cn *p2cn = __UNCONST(pcn); /* XXX: fix the interface */
|
||||
struct sysctlnode sn[SFS_NODEPERDIR];
|
||||
struct sysctlnode qnode;
|
||||
struct puffs_node *pn_dir = opc;
|
||||
struct puffs_node *pn_new;
|
||||
struct sfsnode *sfs_dir = pn_dir->pn_data, *sfs_new;
|
||||
SfsName *sname = PCNPATH(pcn);
|
||||
size_t sl, i;
|
||||
int nodetype;
|
||||
|
||||
assert(ISADIR(sfs_dir));
|
||||
|
||||
/*
|
||||
* If we're looking for dotdot, we already have the entire pathname
|
||||
* in sname, courtesy of pathbuild, so we can skip this step.
|
||||
*/
|
||||
if (!PCNISDOTDOT(pcn)) {
|
||||
memset(&qnode, 0, sizeof(qnode));
|
||||
sl = SFS_NODEPERDIR * sizeof(struct sysctlnode);
|
||||
qnode.sysctl_flags = SYSCTL_VERSION;
|
||||
(*sname)[PCNPLEN(pcn)] = CTL_QUERY;
|
||||
|
||||
if (sysctl(*sname, PCNPLEN(pcn) + 1, sn, &sl,
|
||||
&qnode, sizeof(qnode)) == -1)
|
||||
return ENOENT;
|
||||
|
||||
for (i = 0; i < sl / sizeof(struct sysctlnode); i++)
|
||||
if (strcmp(sn[i].sysctl_name, pcn->pcn_name) == 0)
|
||||
break;
|
||||
if (i == sl / sizeof(struct sysctlnode))
|
||||
return ENOENT;
|
||||
|
||||
(*sname)[PCNPLEN(pcn)] = sn[i].sysctl_num;
|
||||
p2cn->pcn_po_full.po_len++;
|
||||
nodetype = sn[i].sysctl_flags;
|
||||
} else
|
||||
nodetype = CTLTYPE_NODE;
|
||||
|
||||
pn_new = getnode(pu, &p2cn->pcn_po_full, nodetype);
|
||||
sfs_new = pn_new->pn_data;
|
||||
|
||||
puffs_newinfo_setcookie(pni, pn_new);
|
||||
if (ISADIR(sfs_new))
|
||||
puffs_newinfo_setvtype(pni, VDIR);
|
||||
else
|
||||
puffs_newinfo_setvtype(pni, VREG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sysctlfs_node_getattr(struct puffs_usermount *pu, void *opc, struct vattr *va,
|
||||
const struct puffs_cred *pcr)
|
||||
{
|
||||
struct puffs_node *pn = opc;
|
||||
struct sfsnode *sfs = pn->pn_data;
|
||||
|
||||
memset(va, 0, sizeof(struct vattr));
|
||||
|
||||
if (ISADIR(sfs)) {
|
||||
va->va_type = VDIR;
|
||||
va->va_mode = 0555;
|
||||
} else {
|
||||
va->va_type = VREG;
|
||||
va->va_mode = fileperms;
|
||||
}
|
||||
va->va_uid = fileuid;
|
||||
va->va_gid = filegid;
|
||||
va->va_nlink = getlinks(sfs, &pn->pn_po);
|
||||
va->va_fileid = sfs->myid;
|
||||
va->va_size = getsize(sfs, &pn->pn_po);
|
||||
va->va_gen = 1;
|
||||
va->va_rdev = PUFFS_VNOVAL;
|
||||
va->va_blocksize = 512;
|
||||
va->va_filerev = 1;
|
||||
|
||||
va->va_atime = va->va_mtime = va->va_ctime = va->va_birthtime = fstime;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sysctlfs_node_setattr(struct puffs_usermount *pu, void *opc,
|
||||
const struct vattr *va, const struct puffs_cred *pcr)
|
||||
{
|
||||
|
||||
/* dummy, but required for write */
|
||||
/* XXX: we could return EOPNOTSUPP or something */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sysctlfs_node_readdir(struct puffs_usermount *pu, void *opc,
|
||||
struct dirent *dent, off_t *readoff, size_t *reslen,
|
||||
const struct puffs_cred *pcr, int *eofflag,
|
||||
off_t *cookies, size_t *ncookies)
|
||||
{
|
||||
struct sysctlnode sn[SFS_NODEPERDIR];
|
||||
struct sysctlnode qnode;
|
||||
struct puffs_node *pn_dir = opc;
|
||||
struct puffs_node *pn_res;
|
||||
struct puffs_pathobj po;
|
||||
struct sfsnode *sfs_dir = pn_dir->pn_data, *sfs_ent;
|
||||
SfsName *sname;
|
||||
size_t sl, i;
|
||||
enum vtype vt;
|
||||
ino_t id;
|
||||
|
||||
*ncookies = 0;
|
||||
|
||||
again:
|
||||
if (*readoff == DENT_DOT || *readoff == DENT_DOTDOT) {
|
||||
puffs_gendotdent(&dent, sfs_dir->myid, *readoff, reslen);
|
||||
(*readoff)++;
|
||||
PUFFS_STORE_DCOOKIE(cookies, ncookies, *readoff);
|
||||
goto again;
|
||||
}
|
||||
|
||||
memset(&qnode, 0, sizeof(qnode));
|
||||
sl = SFS_NODEPERDIR * sizeof(struct sysctlnode);
|
||||
qnode.sysctl_flags = SYSCTL_VERSION;
|
||||
sname = PNPATH(pn_dir);
|
||||
(*sname)[PNPLEN(pn_dir)] = CTL_QUERY;
|
||||
|
||||
if (sysctl(*sname, PNPLEN(pn_dir) + 1, sn, &sl,
|
||||
&qnode, sizeof(qnode)) == -1)
|
||||
return ENOENT;
|
||||
|
||||
po.po_path = sname;
|
||||
po.po_len = PNPLEN(pn_dir)+1;
|
||||
|
||||
for (i = DENT_ADJ(*readoff); i < sl / sizeof(struct sysctlnode); i++) {
|
||||
if (SYSCTL_TYPE(sn[i].sysctl_flags) == CTLTYPE_NODE)
|
||||
vt = VDIR;
|
||||
else
|
||||
vt = VREG;
|
||||
|
||||
/*
|
||||
* check if the node exists. if so, give it the real
|
||||
* inode number. otherwise just fake it.
|
||||
*/
|
||||
(*sname)[PNPLEN(pn_dir)] = sn[i].sysctl_num;
|
||||
pn_res = puffs_pn_nodewalk(pu, puffs_path_walkcmp, &po);
|
||||
if (pn_res) {
|
||||
sfs_ent = pn_res->pn_data;
|
||||
id = sfs_ent->myid;
|
||||
} else {
|
||||
id = nextid++;
|
||||
}
|
||||
|
||||
if (!puffs_nextdent(&dent, sn[i].sysctl_name, id,
|
||||
puffs_vtype2dt(vt), reslen))
|
||||
return 0;
|
||||
|
||||
(*readoff)++;
|
||||
PUFFS_STORE_DCOOKIE(cookies, ncookies, *readoff);
|
||||
}
|
||||
|
||||
*eofflag = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sysctlfs_node_read(struct puffs_usermount *pu, void *opc, uint8_t *buf,
|
||||
off_t offset, size_t *resid, const struct puffs_cred *pcr,
|
||||
int ioflag)
|
||||
{
|
||||
char localbuf[SFS_MAXFILE];
|
||||
struct puffs_node *pn = opc;
|
||||
struct sfsnode *sfs = pn->pn_data;
|
||||
size_t sz = sizeof(localbuf);
|
||||
int xfer;
|
||||
|
||||
if (ISADIR(sfs))
|
||||
return EISDIR;
|
||||
|
||||
getnodedata(sfs, &pn->pn_po, localbuf, &sz);
|
||||
if ((ssize_t)sz < offset)
|
||||
xfer = 0;
|
||||
else
|
||||
xfer = MIN(*resid, sz - offset);
|
||||
|
||||
if (xfer <= 0)
|
||||
return 0;
|
||||
|
||||
memcpy(buf, localbuf + offset, xfer);
|
||||
*resid -= xfer;
|
||||
|
||||
if (*resid && !rflag) {
|
||||
buf[xfer] = '\n';
|
||||
(*resid)--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sysctlfs_node_write(struct puffs_usermount *pu, void *opc, uint8_t *buf,
|
||||
off_t offset, size_t *resid, const struct puffs_cred *cred,
|
||||
int ioflag)
|
||||
{
|
||||
struct puffs_node *pn = opc;
|
||||
struct sfsnode *sfs = pn->pn_data;
|
||||
long long ll;
|
||||
int i, rv;
|
||||
bool b;
|
||||
|
||||
/*
|
||||
* I picked the wrong day to ... um, the wrong place to return errors
|
||||
*/
|
||||
|
||||
/* easy to support, but just unavailable now */
|
||||
if (rflag)
|
||||
return EOPNOTSUPP;
|
||||
|
||||
if (puffs_cred_isjuggernaut(cred) == 0)
|
||||
return EACCES;
|
||||
|
||||
if (ISADIR(sfs))
|
||||
return EISDIR;
|
||||
|
||||
if (offset != 0)
|
||||
return EINVAL;
|
||||
|
||||
if (ioflag & PUFFS_IO_APPEND)
|
||||
return EINVAL;
|
||||
|
||||
switch (SYSCTL_TYPE(sfs->sysctl_flags)) {
|
||||
case CTLTYPE_BOOL:
|
||||
if (strcasestr((const char *)buf, "true"))
|
||||
b = true;
|
||||
else if (strcasestr((const char *)buf, "false"))
|
||||
b = false;
|
||||
else
|
||||
return EINVAL;
|
||||
rv = sysctl(PNPATH(pn), PNPLEN(pn), NULL, NULL,
|
||||
&b, sizeof(b));
|
||||
break;
|
||||
case CTLTYPE_INT:
|
||||
if (sscanf((const char *)buf, "%d", &i) != 1)
|
||||
return EINVAL;
|
||||
rv = sysctl(PNPATH(pn), PNPLEN(pn), NULL, NULL,
|
||||
&i, sizeof(int));
|
||||
break;
|
||||
case CTLTYPE_QUAD:
|
||||
if (sscanf((const char *)buf, "%lld", &ll) != 1)
|
||||
return EINVAL;
|
||||
rv = sysctl(PNPATH(pn), PNPLEN(pn), NULL, NULL,
|
||||
&ll, sizeof(long long));
|
||||
break;
|
||||
case CTLTYPE_STRING:
|
||||
rv = sysctl(PNPATH(pn), PNPLEN(pn), NULL, NULL, buf, *resid);
|
||||
break;
|
||||
default:
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
*resid = 0;
|
||||
return 0;
|
||||
}
|
||||
14
usr.sbin/puffs/rump_au-naturel/Makefile
Normal file
14
usr.sbin/puffs/rump_au-naturel/Makefile
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# $NetBSD: Makefile,v 1.1 2010/04/29 22:42:48 pooka Exp $
|
||||
#
|
||||
|
||||
PROG= rump_au-naturel
|
||||
NOMAN=
|
||||
|
||||
ISRUMP= # persuadertron
|
||||
|
||||
# Link in components to see which devices they create. The
|
||||
# following is an example. You should see /dev/bpf.
|
||||
#
|
||||
#LDADD+= -lrumpdev_bpf -lrumpdev -lrumpnet_net -lrumpnet
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
66
usr.sbin/puffs/rump_au-naturel/rump_au-naturel.c
Normal file
66
usr.sbin/puffs/rump_au-naturel/rump_au-naturel.c
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/* $NetBSD: rump_au-naturel.c,v 1.1 2010/04/29 22:42:48 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
|
||||
/* NetBSD-5 compat */
|
||||
#ifndef MOUNT_RUMPFS
|
||||
#define MOUNT_RUMPFS "rumpfs"
|
||||
#endif
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: %s rump /mountpoint\n", getprogname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
if (argc != 3)
|
||||
usage();
|
||||
|
||||
rv = p2k_run_fs(MOUNT_RUMPFS, argv[1], argv[2], 0, NULL, 0, 0);
|
||||
if (rv == -1)
|
||||
err(1, "p2k_run_fs");
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
usr.sbin/puffs/rump_cd9660/Makefile
Normal file
9
usr.sbin/puffs/rump_cd9660/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# $NetBSD: Makefile,v 1.3 2010/01/25 15:55:36 pooka Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= cd9660
|
||||
|
||||
ISRUMP= # yes
|
||||
RUMP_DISKFS=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_cd9660/rump_cd9660.8
Normal file
134
usr.sbin/puffs/rump_cd9660/rump_cd9660.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_cd9660.8,v 1.13 2011/07/24 09:00:06 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_CD9660 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_cd9660
|
||||
.Nd mount a cd9660 image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_cd9660 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount cd9660 file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_cd9660 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_cd9660 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar cd9660
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_cd9660 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_cd9660 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
64
usr.sbin/puffs/rump_cd9660/rump_cd9660.c
Normal file
64
usr.sbin/puffs/rump_cd9660/rump_cd9660.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* $NetBSD: rump_cd9660.c,v 1.8 2010/05/30 04:32:09 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <isofs/cd9660/cd9660_mount.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mount_cd9660.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct iso_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
mount_cd9660_parseargs(argc, argv, &args, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
rv = p2k_run_diskfs(MOUNT_CD9660, canon_dev, part, canon_dir, mntflags,
|
||||
&args, sizeof(args), 0);
|
||||
ukfs_part_release(part);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
usr.sbin/puffs/rump_efs/Makefile
Normal file
9
usr.sbin/puffs/rump_efs/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# $NetBSD: Makefile,v 1.3 2010/01/25 15:55:36 pooka Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= efs
|
||||
|
||||
ISRUMP= # gracie, padre
|
||||
RUMP_DISKFS=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_efs/rump_efs.8
Normal file
134
usr.sbin/puffs/rump_efs/rump_efs.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_efs.8,v 1.13 2011/07/24 09:00:06 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_EFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_efs
|
||||
.Nd mount a efs image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_efs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount efs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_efs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_efs 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar efs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_efs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_efs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
63
usr.sbin/puffs/rump_efs/rump_efs.c
Normal file
63
usr.sbin/puffs/rump_efs/rump_efs.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* $NetBSD: rump_efs.c,v 1.6 2009/12/13 21:16:54 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <fs/efs/efs_mount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include "mount_efs.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct efs_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
mount_efs_parseargs(argc, argv, &args, &mntflags, canon_dev, canon_dir);
|
||||
rv = p2k_run_diskfs(MOUNT_EFS, canon_dev, part, canon_dir, mntflags,
|
||||
&args, sizeof(args), 0);
|
||||
ukfs_part_release(part);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
14
usr.sbin/puffs/rump_ext2fs/Makefile
Normal file
14
usr.sbin/puffs/rump_ext2fs/Makefile
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# $NetBSD: Makefile,v 1.6 2010/01/25 15:55:36 pooka Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
MOUNTNAME= ext2fs
|
||||
|
||||
LDADD+= -lrumpfs_ffs
|
||||
DPADD+= ${LIBRUMPFS_FFS}
|
||||
|
||||
ISRUMP= # yea baby
|
||||
RUMP_DISKFS=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_ext2fs/rump_ext2fs.8
Normal file
134
usr.sbin/puffs/rump_ext2fs/rump_ext2fs.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_ext2fs.8,v 1.13 2011/07/24 09:00:06 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_EXT2FS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_ext2fs
|
||||
.Nd mount a ext2fs image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_ext2fs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount ext2fs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_ext2fs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_ext2fs 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar ext2fs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_ext2fs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_ext2fs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
66
usr.sbin/puffs/rump_ext2fs/rump_ext2fs.c
Normal file
66
usr.sbin/puffs/rump_ext2fs/rump_ext2fs.c
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/* $NetBSD: rump_ext2fs.c,v 1.9 2010/01/12 18:43:37 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include "mount_ext2fs.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct ufs_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
mount_ext2fs_parseargs(argc, argv, &args, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
rv = p2k_run_diskfs(MOUNT_EXT2FS, canon_dev, part, canon_dir, mntflags,
|
||||
&args, sizeof(args), 0);
|
||||
ukfs_part_release(part);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
8
usr.sbin/puffs/rump_fdesc/Makefile
Normal file
8
usr.sbin/puffs/rump_fdesc/Makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# $NetBSD: Makefile,v 1.1 2009/07/31 19:18:46 pooka Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= fdesc
|
||||
|
||||
ISRUMP= # descualified
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
96
usr.sbin/puffs/rump_fdesc/rump_fdesc.8
Normal file
96
usr.sbin/puffs/rump_fdesc/rump_fdesc.8
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
.\" $NetBSD: rump_fdesc.8,v 1.6 2011/07/24 09:00:06 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_FDESC 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_fdesc
|
||||
.Nd mount a fdesc fictional fs with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar fdesc
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_fdesc 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount fdesc file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_fdesc 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar fdesc
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_fdesc 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_fdesc 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 6.0 .
|
||||
59
usr.sbin/puffs/rump_fdesc/rump_fdesc.c
Normal file
59
usr.sbin/puffs/rump_fdesc/rump_fdesc.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* $NetBSD: rump_fdesc.c,v 1.1 2009/07/31 19:18:46 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <miscfs/fdesc/fdesc.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
|
||||
#include "mount_fdesc.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
mount_fdesc_parseargs(argc, argv, NULL, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
rv = p2k_run_fs(MOUNT_FDESC, canon_dev, canon_dir, mntflags,
|
||||
NULL, 0, PUFFS_KFLAG_NOCACHE_PAGE);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
11
usr.sbin/puffs/rump_ffs/Makefile
Normal file
11
usr.sbin/puffs/rump_ffs/Makefile
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# $NetBSD: Makefile,v 1.5 2010/01/25 15:55:36 pooka Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
MOUNTNAME= ffs
|
||||
|
||||
ISRUMP= # affirmative
|
||||
RUMP_DISKFS=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_ffs/rump_ffs.8
Normal file
134
usr.sbin/puffs/rump_ffs/rump_ffs.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_ffs.8,v 1.13 2011/07/24 09:00:06 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_FFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_ffs
|
||||
.Nd mount a ffs image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_ffs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount ffs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_ffs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_ffs 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar ffs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_ffs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_ffs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
65
usr.sbin/puffs/rump_ffs/rump_ffs.c
Normal file
65
usr.sbin/puffs/rump_ffs/rump_ffs.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/* $NetBSD: rump_ffs.c,v 1.7 2010/01/12 18:43:37 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include "mount_ffs.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct ufs_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
mount_ffs_parseargs(argc, argv, &args, &mntflags, canon_dev, canon_dir);
|
||||
rv = p2k_run_diskfs(MOUNT_FFS, canon_dev, part, canon_dir,
|
||||
mntflags, &args, sizeof(args), 0);
|
||||
ukfs_part_release(part);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
usr.sbin/puffs/rump_hfs/Makefile
Normal file
9
usr.sbin/puffs/rump_hfs/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# $NetBSD: Makefile,v 1.4 2010/01/25 15:55:36 pooka Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= hfs
|
||||
|
||||
ISRUMP= # rump roast
|
||||
RUMP_DISKFS=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_hfs/rump_hfs.8
Normal file
134
usr.sbin/puffs/rump_hfs/rump_hfs.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_hfs.8,v 1.13 2011/07/24 09:00:07 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_HFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_hfs
|
||||
.Nd mount a hfs image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_hfs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount hfs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_hfs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_hfs 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar hfs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_hfs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_hfs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
63
usr.sbin/puffs/rump_hfs/rump_hfs.c
Normal file
63
usr.sbin/puffs/rump_hfs/rump_hfs.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* $NetBSD: rump_hfs.c,v 1.6 2009/12/13 21:16:54 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <fs/hfs/hfs.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include "mount_hfs.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct hfs_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
mount_hfs_parseargs(argc, argv, &args, &mntflags, canon_dev, canon_dir);
|
||||
rv = p2k_run_diskfs(MOUNT_HFS, canon_dev, part, canon_dir, mntflags,
|
||||
&args, sizeof(args), 0);
|
||||
ukfs_part_release(part);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
8
usr.sbin/puffs/rump_kernfs/Makefile
Normal file
8
usr.sbin/puffs/rump_kernfs/Makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# $NetBSD: Makefile,v 1.1 2010/03/31 14:22:27 pooka Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= kernfs
|
||||
|
||||
ISRUMP= # syndicate
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
96
usr.sbin/puffs/rump_kernfs/rump_kernfs.8
Normal file
96
usr.sbin/puffs/rump_kernfs/rump_kernfs.8
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
.\" $NetBSD: rump_kernfs.8,v 1.6 2011/07/24 09:00:07 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_KERNFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_kernfs
|
||||
.Nd mount a kernfs fictional fs with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar kernfs
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_kernfs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount kernfs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_kernfs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar kernfs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_kernfs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_kernfs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 6.0 .
|
||||
57
usr.sbin/puffs/rump_kernfs/rump_kernfs.c
Normal file
57
usr.sbin/puffs/rump_kernfs/rump_kernfs.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* $NetBSD: rump_kernfs.c,v 1.1 2010/03/31 14:22:27 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
|
||||
#include "mount_kernfs.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
mount_kernfs_parseargs(argc, argv, NULL, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
rv = p2k_run_fs(MOUNT_KERNFS, canon_dev, canon_dir, mntflags,
|
||||
NULL, 0, PUFFS_KFLAG_NOCACHE);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
22
usr.sbin/puffs/rump_lfs/Makefile
Normal file
22
usr.sbin/puffs/rump_lfs/Makefile
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# $NetBSD: Makefile,v 1.10 2014/03/04 21:06:47 joerg Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
MOUNTNAME= lfs
|
||||
|
||||
LDADD+= -lrumpfs_ffs
|
||||
DPADD+= ${LIBRUMPFS_FFS}
|
||||
|
||||
ISRUMP= # don't deny it
|
||||
RUMP_DISKFS=
|
||||
|
||||
CPPFLAGS+= -DUSE_RUMP -DLFS_CLEANER_AS_LIB
|
||||
|
||||
CWARNFLAGS.clang+= -Wno-error=absolute-value
|
||||
|
||||
.include "../../../libexec/lfs_cleanerd/Makefile.inc"
|
||||
|
||||
#DBG=-g
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_lfs/rump_lfs.8
Normal file
134
usr.sbin/puffs/rump_lfs/rump_lfs.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_lfs.8,v 1.13 2011/07/24 09:00:07 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_LFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_lfs
|
||||
.Nd mount a lfs image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_lfs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount lfs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_lfs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_lfs 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar lfs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_lfs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_lfs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
130
usr.sbin/puffs/rump_lfs/rump_lfs.c
Normal file
130
usr.sbin/puffs/rump_lfs/rump_lfs.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/* $NetBSD: rump_lfs.c,v 1.18 2015/08/02 18:11:57 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <pthread.h>
|
||||
#include <puffs.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include "mount_lfs.h"
|
||||
|
||||
static void *
|
||||
cleaner(void *arg)
|
||||
{
|
||||
const char *the_argv[7];
|
||||
|
||||
the_argv[0] = "megamaid";
|
||||
the_argv[1] = "-D"; /* don't fork() & detach */
|
||||
the_argv[2] = arg;
|
||||
|
||||
lfs_cleaner_main(3, __UNCONST(the_argv));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct ulfs_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
char rawdev[MAXPATHLEN];
|
||||
struct p2k_mount *p2m;
|
||||
pthread_t cleanerthread;
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
if (argc >= 3) {
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
if (part != ukfs_part_none) {
|
||||
errx(1, "lfs does not currently support "
|
||||
"embedded partitions");
|
||||
}
|
||||
}
|
||||
mount_lfs_parseargs(argc, argv, &args, &mntflags, canon_dev, canon_dir);
|
||||
|
||||
/* Reset getopt for lfs_cleaner_main. */
|
||||
optreset = 1;
|
||||
optind = 1;
|
||||
|
||||
p2m = p2k_init(0);
|
||||
if (!p2m)
|
||||
err(1, "init p2k");
|
||||
/*
|
||||
* XXX: this particular piece inspired by the cleaner code.
|
||||
* obviously FIXXXME along with the cleaner.
|
||||
*/
|
||||
sprintf(rawdev, "/dev/r%s", canon_dev+5);
|
||||
rump_pub_etfs_register(rawdev, canon_dev, RUMP_ETFS_CHR);
|
||||
|
||||
/*
|
||||
* We basically have two choices:
|
||||
* 1) run the cleaner in another process and do rump ipc syscalls
|
||||
* 2) run it off a thread in this process and do rump syscalls
|
||||
* as function calls.
|
||||
*
|
||||
* opt for "2" for now
|
||||
*/
|
||||
#ifdef CLEANER_TESTING
|
||||
ukfs_mount(MOUNT_LFS, canon_dev, canon_dir, mntflags,
|
||||
&args, sizeof(args));
|
||||
cleaner(canon_dir);
|
||||
#endif
|
||||
if (p2k_setup_diskfs(p2m, MOUNT_LFS, canon_dev, part, canon_dir,
|
||||
mntflags, &args, sizeof(args)) == -1)
|
||||
err(1, "mount");
|
||||
ukfs_part_release(part);
|
||||
|
||||
#ifndef CLEANER_TESTING
|
||||
if ((mntflags & MNT_RDONLY) == 0) {
|
||||
if (pthread_create(&cleanerthread, NULL,
|
||||
cleaner, canon_dir) == -1)
|
||||
err(1, "cannot start cleaner");
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = p2k_mainloop(p2m);
|
||||
if (rv == -1)
|
||||
err(1, "fs service");
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
usr.sbin/puffs/rump_msdos/Makefile
Normal file
9
usr.sbin/puffs/rump_msdos/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# $NetBSD: Makefile,v 1.4 2010/01/25 15:55:36 pooka Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= msdos
|
||||
|
||||
ISRUMP= # rump, si
|
||||
RUMP_DISKFS= # si2
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_msdos/rump_msdos.8
Normal file
134
usr.sbin/puffs/rump_msdos/rump_msdos.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_msdos.8,v 1.13 2011/07/24 09:00:07 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_MSDOS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_msdos
|
||||
.Nd mount a msdos image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_msdos 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount msdos file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_msdos 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_msdos 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar msdos
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_msdos 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_msdos 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
66
usr.sbin/puffs/rump_msdos/rump_msdos.c
Normal file
66
usr.sbin/puffs/rump_msdos/rump_msdos.c
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/* $NetBSD: rump_msdos.c,v 1.8 2010/01/12 18:43:37 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <msdosfs/msdosfsmount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include "mount_msdos.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct msdosfs_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
mount_msdos_parseargs(argc, argv, &args, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
rv = p2k_run_diskfs(MOUNT_MSDOS, canon_dev, part, canon_dir, mntflags,
|
||||
&args, sizeof(args), 0);
|
||||
ukfs_part_release(part);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
14
usr.sbin/puffs/rump_nfs/Makefile
Normal file
14
usr.sbin/puffs/rump_nfs/Makefile
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# $NetBSD: Makefile,v 1.6 2010/07/20 14:42:03 pooka Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
MOUNTNAME= nfs
|
||||
|
||||
SRCS+= getnfsargs.c
|
||||
LDADD+= -lrumpfs_nfs -lrumpnet -lrumpnet_sockin
|
||||
|
||||
ISRUMP= # gives me nightmares
|
||||
#CPPFLAGS+= -DINET6 # for getnfsargs?
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
110
usr.sbin/puffs/rump_nfs/rump_nfs.8
Normal file
110
usr.sbin/puffs/rump_nfs/rump_nfs.8
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
.\" $NetBSD: rump_nfs.8,v 1.11 2011/07/24 09:00:07 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_NFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_nfs
|
||||
.Nd mount a nfs share with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar share
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_nfs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount nfs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_nfs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
Even though the
|
||||
.Nm
|
||||
file system client runs within a virtual rump kernel in userspace,
|
||||
it uses host network services
|
||||
.Pq by means of Dq rump sockin .
|
||||
This means that regardless of whether using
|
||||
.Nm
|
||||
or
|
||||
.Xr mount_nfs 8 ,
|
||||
the same network configurations will be used.
|
||||
Currently,
|
||||
.Dq sockin
|
||||
supports IPv4.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar nfs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_nfs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_nfs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
62
usr.sbin/puffs/rump_nfs/rump_nfs.c
Normal file
62
usr.sbin/puffs/rump_nfs/rump_nfs.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/* $NetBSD: rump_nfs.c,v 1.10 2010/01/12 18:43:37 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <nfs/nfsmount.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/p2k.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mount_nfs.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct nfs_args args;
|
||||
char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
int rv, mntflags;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
mount_nfs_parseargs(argc, argv, &args, &mntflags, canon_dev, canon_dir);
|
||||
|
||||
rv = p2k_run_fs(MOUNT_NFS, canon_dev, canon_dir, mntflags, &args,
|
||||
sizeof(args), PUFFS_KFLAG_WTCACHE);
|
||||
if (rv == -1)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
12
usr.sbin/puffs/rump_nqmfs/Makefile
Normal file
12
usr.sbin/puffs/rump_nqmfs/Makefile
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# $NetBSD: Makefile,v 1.1 2010/03/08 12:46:33 pooka Exp $
|
||||
#
|
||||
|
||||
PROG= rump_nqmfs
|
||||
|
||||
LDADD+= -lrumpfs_mfs -lrumpfs_ffs
|
||||
|
||||
ISRUMP= # affirmative
|
||||
NOMAN= # si, signor
|
||||
RUMP_DISKFS= # well, uh, yea, but there's ffs
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
131
usr.sbin/puffs/rump_nqmfs/rump_nqmfs.c
Normal file
131
usr.sbin/puffs/rump_nqmfs/rump_nqmfs.c
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/* $NetBSD: rump_nqmfs.c,v 1.3 2010/03/31 14:54:07 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Not Quite MFS. Instead of allocating memory and creating a FFS file system
|
||||
* there, mmap a file (which should contain ffs) and use that as the backend.
|
||||
* You can also give a newly created image as the file ...
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <mntopts.h>
|
||||
#include <puffs.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
const struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
MOPT_NULL,
|
||||
};
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "%s: [-o args] fspec mountpoint\n", getprogname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static struct mfs_args args;
|
||||
static char *mntpath, *mntfile;
|
||||
static int mntflags, altflags;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct stat sb;
|
||||
mntoptparse_t mp;
|
||||
void *membase;
|
||||
int ch, fd, rdonly, shared;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
shared = mntflags = altflags = 0;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
while ((ch = getopt(argc, argv, "o:s")) != -1) {
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
mp = getmntopts(optarg, mopts, &mntflags, &altflags);
|
||||
if (mp == NULL)
|
||||
err(1, "getmntopts");
|
||||
freemntopts(mp);
|
||||
break;
|
||||
case 's':
|
||||
shared = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 2)
|
||||
usage();
|
||||
mntfile = argv[0];
|
||||
mntpath = argv[1];
|
||||
rdonly = mntflags & MNT_RDONLY;
|
||||
|
||||
if (stat(mntfile, &sb) == -1)
|
||||
err(1, "stat fspec");
|
||||
if (!S_ISREG(sb.st_mode))
|
||||
errx(1, "fspec must be a regular file");
|
||||
|
||||
fd = open(mntfile, rdonly ? O_RDONLY: O_RDWR);
|
||||
if (fd == -1)
|
||||
err(1, "open fspec");
|
||||
|
||||
membase = mmap(NULL, sb.st_size, PROT_READ | (rdonly ? 0 : PROT_WRITE),
|
||||
MAP_FILE | (shared ? MAP_SHARED : MAP_PRIVATE), fd, 0);
|
||||
if (membase == MAP_FAILED)
|
||||
err(1, "cannot mmap fspec");
|
||||
|
||||
args.fspec = mntfile;
|
||||
args.base = membase;
|
||||
args.size = sb.st_size;
|
||||
|
||||
if (p2k_run_fs(MOUNT_MFS, "/swabbie", mntpath,
|
||||
0, &args, sizeof(args), 0) == -1)
|
||||
err(1, "p2k");
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
usr.sbin/puffs/rump_ntfs/Makefile
Normal file
9
usr.sbin/puffs/rump_ntfs/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# $NetBSD: Makefile,v 1.3 2010/01/25 15:55:37 pooka Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= ntfs
|
||||
|
||||
ISRUMP= # only for you sir, only for you
|
||||
RUMP_DISKFS=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_ntfs/rump_ntfs.8
Normal file
134
usr.sbin/puffs/rump_ntfs/rump_ntfs.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_ntfs.8,v 1.13 2011/07/24 09:00:07 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_NTFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_ntfs
|
||||
.Nd mount a ntfs image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_ntfs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount ntfs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_ntfs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_ntfs 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar ntfs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_ntfs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_ntfs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
64
usr.sbin/puffs/rump_ntfs/rump_ntfs.c
Normal file
64
usr.sbin/puffs/rump_ntfs/rump_ntfs.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* $NetBSD: rump_ntfs.c,v 1.6 2009/12/13 21:16:55 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <ntfs/ntfsmount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include "mount_ntfs.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct ntfs_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
mount_ntfs_parseargs(argc, argv, &args, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
rv = p2k_run_diskfs(MOUNT_NTFS, canon_dev, part, canon_dir, mntflags,
|
||||
&args, sizeof(args), 0);
|
||||
ukfs_part_release(part);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
20
usr.sbin/puffs/rump_smbfs/Makefile
Normal file
20
usr.sbin/puffs/rump_smbfs/Makefile
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# $NetBSD: Makefile,v 1.7 2013/12/25 23:35:17 christos Exp $
|
||||
#
|
||||
|
||||
SMBROOT=${.CURDIR}/../../../external/bsd/smbfs
|
||||
|
||||
MOUNTNAME= smbfs
|
||||
SRCS+= smb_rumpops.c
|
||||
|
||||
PROGDPLIBS+= smb ${SMBROOT}/lib/libsmb
|
||||
LDADD+= -lrumpnet_sockin -lrumpnet
|
||||
LDADD+= -lrumpkern_crypto -lrumpdev_netsmb -lrumpdev
|
||||
|
||||
ISRUMP= # it is
|
||||
|
||||
.include "${SMBROOT}/Makefile.inc"
|
||||
|
||||
CPPFLAGS+=-I${SMBDIST}/mount_smbfs
|
||||
.PATH: ${SMBDIST}/mount_smbfs
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
110
usr.sbin/puffs/rump_smbfs/rump_smbfs.8
Normal file
110
usr.sbin/puffs/rump_smbfs/rump_smbfs.8
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
.\" $NetBSD: rump_smbfs.8,v 1.6 2011/07/24 09:00:07 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_SMBFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_smbfs
|
||||
.Nd mount a smbfs share with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar share
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_smbfs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount smbfs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_smbfs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
Even though the
|
||||
.Nm
|
||||
file system client runs within a virtual rump kernel in userspace,
|
||||
it uses host network services
|
||||
.Pq by means of Dq rump sockin .
|
||||
This means that regardless of whether using
|
||||
.Nm
|
||||
or
|
||||
.Xr mount_smbfs 8 ,
|
||||
the same network configurations will be used.
|
||||
Currently,
|
||||
.Dq sockin
|
||||
supports IPv4.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar smbfs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_smbfs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_smbfs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 6.0 .
|
||||
80
usr.sbin/puffs/rump_smbfs/rump_smbfs.c
Normal file
80
usr.sbin/puffs/rump_smbfs/rump_smbfs.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/* $NetBSD: rump_smbfs.c,v 1.6 2010/01/12 18:43:37 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <fs/smbfs/smbfs.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/p2k.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mount_smbfs.h"
|
||||
|
||||
struct p2k_mount *docancel;
|
||||
static void
|
||||
pcancel(void)
|
||||
{
|
||||
|
||||
if (docancel)
|
||||
p2k_cancel(docancel, 0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct smbfs_args args;
|
||||
char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct p2k_mount *p2m;
|
||||
int mntflags;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
p2m = p2k_init(PUFFS_KFLAG_WTCACHE);
|
||||
atexit(pcancel);
|
||||
docancel = p2m;
|
||||
/* XXX: this will exit upon error. therefore kludge with atexit */
|
||||
mount_smbfs_parseargs(argc, argv, &args, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
docancel = NULL;
|
||||
|
||||
if (p2k_setup_fs(p2m, MOUNT_SMBFS, canon_dev, canon_dir, mntflags,
|
||||
&args, sizeof(args)) == -1)
|
||||
err(1, "mount");
|
||||
if (p2k_mainloop(p2m) == -1)
|
||||
err(1, "fs service");
|
||||
|
||||
return 0;
|
||||
}
|
||||
52
usr.sbin/puffs/rump_smbfs/smb_rumpops.c
Normal file
52
usr.sbin/puffs/rump_smbfs/smb_rumpops.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/* $NetBSD: smb_rumpops.c,v 1.1 2009/09/06 20:26:47 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: smb_rumpops.c,v 1.1 2009/09/06 20:26:47 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
|
||||
#include "smb_kernelops.h"
|
||||
|
||||
const struct smb_kernelops smb_kops = {
|
||||
.ko_open = rump_sys_open,
|
||||
.ko_ioctl = rump_sys_ioctl,
|
||||
.ko_close = rump_sys_close,
|
||||
|
||||
.ko_socket = rump_sys_socket,
|
||||
.ko_setsockopt = rump_sys_setsockopt,
|
||||
.ko_bind = rump_sys_bind,
|
||||
.ko_sendto = rump_sys_sendto,
|
||||
.ko_recvfrom = rump_sys_recvfrom,
|
||||
};
|
||||
13
usr.sbin/puffs/rump_syspuffs/Makefile
Normal file
13
usr.sbin/puffs/rump_syspuffs/Makefile
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# $NetBSD: Makefile,v 1.4 2010/06/30 16:22:49 pooka Exp $
|
||||
#
|
||||
|
||||
PROG= rump_syspuffs
|
||||
|
||||
LDADD+= -lrumpfs_syspuffs -lrumpdev_putter
|
||||
DPADD+= ${LIBRUMPFS_SYSPUFFS}
|
||||
|
||||
ISRUMP= # indubitably
|
||||
CPPFLAGS+= -I${.CURDIR}/../../../sys/rump/fs/lib/libsyspuffs
|
||||
MAN= rump_syspuffs.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
73
usr.sbin/puffs/rump_syspuffs/rump_syspuffs.8
Normal file
73
usr.sbin/puffs/rump_syspuffs/rump_syspuffs.8
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
.\" $NetBSD: rump_syspuffs.8,v 1.4 2012/11/14 23:11:27 njoly Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2008 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd June 9, 2009
|
||||
.Dt RUMP_SYSPUFFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_syspuffs
|
||||
.Nd mount a puffs file server with a userspace puffs loop
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Ar "file_server"
|
||||
.Ar arguments
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount any
|
||||
.Xr puffs 3
|
||||
file server so that the requests are passed through the kernel
|
||||
puffs code in userspace as well.
|
||||
Therefore the approximate callgraph looks a little like the following,
|
||||
where k and u denote code running in the kernel space and userspace,
|
||||
respectively:
|
||||
puffs vfs (k) \(-> libpuffs (u) \(-> p2k (u) \(-> puffs vfs (u) \(->
|
||||
libpuffs (u) \(-> file server (u).
|
||||
The response path is the same, but in reverse.
|
||||
.Pp
|
||||
In its current state,
|
||||
.Nm
|
||||
is most useful as a proof of concept for file system distribution
|
||||
and for developing and debugging the kernel portion of puffs.
|
||||
.Sh EXAMPLES
|
||||
Mount a file system with sshfs:
|
||||
.Dl rump_syspuffs mount_psshfs server.address /mnt
|
||||
.Pp
|
||||
Mount an ntfs file system using ntfs-3g (from pkgsrc/filesystems/fuse-ntfs-3g),
|
||||
set the default uid to 1323:
|
||||
.Dl rump_syspuffs ntfs-3g -o uid=1323 /path/to/filesystem /mnt
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr puffs 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
debugging utility first appeared in
|
||||
.Nx 5.0 .
|
||||
155
usr.sbin/puffs/rump_syspuffs/rump_syspuffs.c
Normal file
155
usr.sbin/puffs/rump_syspuffs/rump_syspuffs.c
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/* $NetBSD: rump_syspuffs.c,v 1.12 2011/08/31 13:32:39 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Development of this software was supported by the
|
||||
* Research Foundation of Helsinki University of Technology
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/syslimits.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <paths.h>
|
||||
#include <puffs.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
|
||||
#include "rump_syspuffs.h"
|
||||
|
||||
#ifndef MOUNT_NOMAIN
|
||||
#include <rump/p2k.h>
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct syspuffs_args args;
|
||||
int mntflags, rv;
|
||||
|
||||
#if 0
|
||||
extern int rumpns_puffsdebug;
|
||||
extern int rumpns_putterdebug;
|
||||
|
||||
rumpns_puffsdebug = rumpns_putterdebug = 1;
|
||||
#endif
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
mount_syspuffs_parseargs(argc, argv, &args, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
|
||||
rv = p2k_run_fs(MOUNT_PUFFS, canon_dev, canon_dir, mntflags,
|
||||
&args.us_kargs, sizeof(args.us_kargs), args.us_pflags);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* MOUNT_NOMAIN */
|
||||
|
||||
__dead static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
errx(1, "%s: server server_parameters", getprogname());
|
||||
}
|
||||
|
||||
void
|
||||
mount_syspuffs_parseargs(int argc, char *argv[],
|
||||
struct syspuffs_args *args, int *mntflags,
|
||||
char *canon_dev, char *canon_dir)
|
||||
{
|
||||
struct puffs_kargs *kargs = &args->us_kargs;
|
||||
int *pflags = &args->us_pflags;
|
||||
char comfd[16];
|
||||
int sv[2];
|
||||
size_t len;
|
||||
int rv;
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
/* Create sucketpair for communication with the real file server */
|
||||
if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) == -1)
|
||||
err(1, "socketpair");
|
||||
|
||||
if ((rv = rump_init()) == -1)
|
||||
err(1, "rump_init");
|
||||
|
||||
switch (fork()) {
|
||||
case 0:
|
||||
close(sv[1]);
|
||||
snprintf(comfd, sizeof(sv[0]), "%d", sv[0]);
|
||||
if (setenv("PUFFS_COMFD", comfd, 1) == -1)
|
||||
err(1, "setenv");
|
||||
|
||||
argv++;
|
||||
if (execvp(argv[0], argv) == -1)
|
||||
err(1, "execvp");
|
||||
/*NOTREACHED*/
|
||||
case -1:
|
||||
err(1, "fork");
|
||||
/*NOTREACHED*/
|
||||
default:
|
||||
close(sv[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* read args */
|
||||
if (read(sv[1], &len, sizeof(len)) != sizeof(len))
|
||||
err(1, "mp 1");
|
||||
if (len > MAXPATHLEN)
|
||||
err(1, "mntpath > MAXPATHLEN");
|
||||
if ((size_t)read(sv[1], canon_dir, len) != len)
|
||||
err(1, "mp 2");
|
||||
if (read(sv[1], &len, sizeof(len)) != sizeof(len))
|
||||
err(1, "fn 1");
|
||||
if (len > MAXPATHLEN)
|
||||
err(1, "devpath > MAXPATHLEN");
|
||||
if ((size_t)read(sv[1], canon_dev, len) != len)
|
||||
err(1, "fn 2");
|
||||
if (read(sv[1], mntflags, sizeof(*mntflags)) != sizeof(*mntflags))
|
||||
err(1, "mntflags");
|
||||
if (read(sv[1], kargs, sizeof(len)) != sizeof(len)) /* unused now */
|
||||
err(1, "unused len");
|
||||
if (read(sv[1], kargs, sizeof(*kargs)) != sizeof(*kargs))
|
||||
err(1, "puffs_args");
|
||||
if (read(sv[1], pflags, sizeof(*pflags)) != sizeof(*pflags))
|
||||
err(1, "pflags");
|
||||
|
||||
/* XXX: some adjustments */
|
||||
*pflags |= PUFFS_KFLAG_NOCACHE;
|
||||
*pflags &= ~PUFFS_FLAG_BUILDPATH;
|
||||
|
||||
rv = rump_pub_syspuffs_glueinit(sv[1], &kargs->pa_fd);
|
||||
assert(rv == 0);
|
||||
}
|
||||
45
usr.sbin/puffs/rump_syspuffs/rump_syspuffs.h
Normal file
45
usr.sbin/puffs/rump_syspuffs/rump_syspuffs.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/* $NetBSD: rump_syspuffs.h,v 1.1 2008/09/02 21:14:32 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _USR_SBIN_PUFFS_RUMP_SYSPUFFS_MOUNT_SYSPUFFS_H_
|
||||
#define _USR_SBIN_PUFFS_RUMP_SYSPUFFS_MOUNT_SYSPUFFS_H_
|
||||
|
||||
#include <puffs.h>
|
||||
|
||||
struct syspuffs_args {
|
||||
struct puffs_kargs us_kargs;
|
||||
int us_pflags;
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
void mount_syspuffs_parseargs(int, char **, struct syspuffs_args *,
|
||||
int *, char *, char *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _USR_SBIN_PUFFS_RUMP_SYSPUFFS_MOUNT_SYSPUFFS_H_ */
|
||||
8
usr.sbin/puffs/rump_sysvbfs/Makefile
Normal file
8
usr.sbin/puffs/rump_sysvbfs/Makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# $NetBSD: Makefile,v 1.3 2009/01/05 15:39:34 pooka Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= sysvbfs
|
||||
|
||||
ISRUMP= # oui
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_sysvbfs/rump_sysvbfs.8
Normal file
134
usr.sbin/puffs/rump_sysvbfs/rump_sysvbfs.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_sysvbfs.8,v 1.13 2011/07/24 09:00:07 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_SYSVBFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_sysvbfs
|
||||
.Nd mount a sysvbfs image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_sysvbfs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount sysvbfs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_sysvbfs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_sysvbfs 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar sysvbfs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_sysvbfs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_sysvbfs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
64
usr.sbin/puffs/rump_sysvbfs/rump_sysvbfs.c
Normal file
64
usr.sbin/puffs/rump_sysvbfs/rump_sysvbfs.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* $NetBSD: rump_sysvbfs.c,v 1.5 2010/01/12 18:43:38 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mount_sysvbfs.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct sysvbfs_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
mount_sysvbfs_parseargs(argc, argv, &args, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
rv = p2k_run_diskfs(MOUNT_SYSVBFS, canon_dev, part, canon_dir, mntflags,
|
||||
&args, sizeof(args), 0);
|
||||
ukfs_part_release(part);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
8
usr.sbin/puffs/rump_tmpfs/Makefile
Normal file
8
usr.sbin/puffs/rump_tmpfs/Makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# $NetBSD: Makefile,v 1.2 2008/08/05 20:57:46 pooka Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= tmpfs
|
||||
|
||||
ISRUMP= # the cock of the walk, baby
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
96
usr.sbin/puffs/rump_tmpfs/rump_tmpfs.8
Normal file
96
usr.sbin/puffs/rump_tmpfs/rump_tmpfs.8
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
.\" $NetBSD: rump_tmpfs.8,v 1.13 2011/07/24 09:00:08 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_TMPFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_tmpfs
|
||||
.Nd mount a tmpfs fictional fs with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar tmpfs
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_tmpfs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount tmpfs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_tmpfs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar tmpfs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_tmpfs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_tmpfs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
71
usr.sbin/puffs/rump_tmpfs/rump_tmpfs.c
Normal file
71
usr.sbin/puffs/rump_tmpfs/rump_tmpfs.c
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/* $NetBSD: rump_tmpfs.c,v 1.4 2009/12/17 14:06:38 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <fs/tmpfs/tmpfs_args.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
|
||||
#include "mount_tmpfs.h"
|
||||
|
||||
/*
|
||||
* tmpfs has a slight "issue" with file content storage. Since it
|
||||
* stores data in memory, we will end up using 2x the RAM for
|
||||
* storage if we cache in puffs vfs. If we don't, we need to take
|
||||
* the slow path from the kernel to the file server every time the
|
||||
* file is accessed. It's either suck or suck. However, rump_tmpfs
|
||||
* will not be used in real life, so this is hardly a release-stopping
|
||||
* issue of catastrophic proportions. For now we opt for un-double
|
||||
* storage (PUFFS_KFLAG_NOCACHE_PAGE).
|
||||
*/
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct tmpfs_args args;
|
||||
char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
mount_tmpfs_parseargs(argc, argv, &args, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
rv = p2k_run_fs(MOUNT_TMPFS, canon_dev, canon_dir, mntflags,
|
||||
&args, sizeof(args), PUFFS_KFLAG_NOCACHE_PAGE);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
usr.sbin/puffs/rump_udf/Makefile
Normal file
9
usr.sbin/puffs/rump_udf/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# $NetBSD: Makefile,v 1.3 2010/01/25 15:55:37 pooka Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= udf
|
||||
|
||||
ISRUMP= # more cowbell
|
||||
RUMP_DISKFS=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_udf/rump_udf.8
Normal file
134
usr.sbin/puffs/rump_udf/rump_udf.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_udf.8,v 1.13 2011/07/24 09:00:08 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_UDF 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_udf
|
||||
.Nd mount a udf image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_udf 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount udf file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_udf 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_udf 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar udf
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_udf 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_udf 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 5.0 .
|
||||
65
usr.sbin/puffs/rump_udf/rump_udf.c
Normal file
65
usr.sbin/puffs/rump_udf/rump_udf.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/* $NetBSD: rump_udf.c,v 1.7 2010/01/12 18:43:38 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <fs/udf/udf_mount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include "mount_udf.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct udf_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
mount_udf_parseargs(argc, argv, &args, &mntflags, canon_dev, canon_dir);
|
||||
rv = p2k_run_diskfs(MOUNT_UDF, canon_dev, part, canon_dir, mntflags,
|
||||
&args, sizeof(args), 0);
|
||||
ukfs_part_release(part);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
usr.sbin/puffs/rump_v7fs/Makefile
Normal file
9
usr.sbin/puffs/rump_v7fs/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# $NetBSD: Makefile,v 1.2 2011/11/14 11:28:05 njoly Exp $
|
||||
#
|
||||
|
||||
MOUNTNAME= v7fs
|
||||
|
||||
ISRUMP= # oui
|
||||
RUMP_DISKFS=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
134
usr.sbin/puffs/rump_v7fs/rump_v7fs.8
Normal file
134
usr.sbin/puffs/rump_v7fs/rump_v7fs.8
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" $NetBSD: rump_v7fs.8,v 1.1 2011/07/24 08:55:31 uch Exp $
|
||||
.\"
|
||||
.\" WARNING: GENERATED FILE, DO NOT EDIT
|
||||
.\" INSTEAD, EDIT makerumpmanpages.sh AND REGEN
|
||||
.\" from: NetBSD: makerumpmanpages.sh,v 1.12 2010/11/22 07:56:31 pooka Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2008-2010 Antti Kantee. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 21, 2010
|
||||
.Dt RUMP_V7FS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rump_v7fs
|
||||
.Nd mount a v7fs image with a userspace server
|
||||
.Sh SYNOPSIS
|
||||
.Cd "file-system PUFFS"
|
||||
.Cd "pseudo-device putter"
|
||||
.Pp
|
||||
.Nm
|
||||
.Op options
|
||||
.Ar image
|
||||
.Ar mountpoint
|
||||
.Sh DESCRIPTION
|
||||
.Em NOTE!
|
||||
This manual page describes features specific to the
|
||||
.Xr rump 3
|
||||
file server.
|
||||
Please see
|
||||
.Xr mount_v7fs 8
|
||||
for a full description of the available command line options.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
utility can be used to mount v7fs file systems.
|
||||
It uses
|
||||
.Xr rump 3
|
||||
and
|
||||
.Xr p2k 3
|
||||
to facilitate running the file system as a server in userspace.
|
||||
As opposed to
|
||||
.Xr mount_v7fs 8 ,
|
||||
.Nm
|
||||
does not use file system code within the kernel and therefore does
|
||||
not require kernel support except
|
||||
.Xr puffs 4 .
|
||||
Apart from a minor speed penalty there is no downside with respect to
|
||||
in-kernel code.
|
||||
.Pp
|
||||
.Nm
|
||||
does not require using
|
||||
.Xr vnconfig 8
|
||||
for mounts from regular files and the file path can be passed
|
||||
directly as the
|
||||
.Ar image
|
||||
parameter.
|
||||
In fact, the use of
|
||||
.Xr vnconfig 8
|
||||
is discouraged, since it is unable to properly deal with images on
|
||||
sparse files.
|
||||
.Pp
|
||||
In case the image contains multiple partitions, the desired partition
|
||||
must be indicated by appending the token
|
||||
.Dq %DISKLABEL:p%
|
||||
to the
|
||||
.Ar image
|
||||
path.
|
||||
The letter
|
||||
.Dq p
|
||||
specifies the partition as obtained via
|
||||
.Xr disklabel 8 .
|
||||
For example, to mount partition
|
||||
.Dq e
|
||||
from image
|
||||
.Pa /tmp/wd0.img ,
|
||||
use
|
||||
.Dq /tmp/wd0.img%DISKLABEL:e% .
|
||||
.Pp
|
||||
It is recommended that untrusted file system images be mounted with
|
||||
.Nm
|
||||
instead of
|
||||
.Xr mount_v7fs 8 .
|
||||
Corrupt file system images commonly cause the file system
|
||||
to crash the entire kernel, but with
|
||||
.Nm
|
||||
only the userspace server process will dump core.
|
||||
.Pp
|
||||
To use
|
||||
.Nm
|
||||
via
|
||||
.Xr mount 8 ,
|
||||
the flags
|
||||
.Fl o Ar rump
|
||||
and
|
||||
.Fl t Ar v7fs
|
||||
should be given.
|
||||
Similarly,
|
||||
.Nm
|
||||
is used instead of
|
||||
.Xr mount_v7fs 8
|
||||
if
|
||||
.Dq rump
|
||||
is added to the options field of
|
||||
.Xr fstab 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr p2k 3 ,
|
||||
.Xr puffs 3 ,
|
||||
.Xr rump 3 ,
|
||||
.Xr mount_v7fs 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 6.0 .
|
||||
64
usr.sbin/puffs/rump_v7fs/rump_v7fs.c
Normal file
64
usr.sbin/puffs/rump_v7fs/rump_v7fs.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* $NetBSD: rump_v7fs.c,v 1.1 2011/07/24 08:55:31 uch Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <rump/p2k.h>
|
||||
#include <rump/ukfs.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <puffs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mount_v7fs.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct v7fs_args args;
|
||||
char canon_dev[UKFS_DEVICE_MAXPATHLEN], canon_dir[MAXPATHLEN];
|
||||
struct ukfs_part *part;
|
||||
int mntflags;
|
||||
int rv;
|
||||
|
||||
setprogname(argv[0]);
|
||||
puffs_unmountonsignal(SIGINT, true);
|
||||
puffs_unmountonsignal(SIGTERM, true);
|
||||
|
||||
UKFS_DEVICE_ARGVPROBE(&part);
|
||||
mount_v7fs_parseargs(argc, argv, &args, &mntflags,
|
||||
canon_dev, canon_dir);
|
||||
rv = p2k_run_diskfs(MOUNT_V7FS, canon_dev, part, canon_dir, mntflags,
|
||||
&args, sizeof(args), 0);
|
||||
ukfs_part_release(part);
|
||||
if (rv)
|
||||
err(1, "mount");
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user