rump: import libukfs

This commit is contained in:
Jean-Baptiste Boric 2016-12-26 22:34:54 +01:00
parent dba634132e
commit 3ebab8327b
11 changed files with 2198 additions and 1 deletions

View File

@ -1112,6 +1112,9 @@
./usr/lib/libtermlib.so minix-base
./usr/lib/libtermlib.so.0 minix-base
./usr/lib/libtermlib.so.0.6 minix-base
./usr/lib/libukfs.so.1.0 minix-base rump
./usr/lib/libukfs.so.1 minix-base rump
./usr/lib/libukfs.so minix-base rump
./usr/lib/libutil.so minix-base
./usr/lib/libutil.so.7 minix-base
./usr/lib/libutil.so.7.21 minix-base obsolete

View File

@ -1735,6 +1735,7 @@
./usr/include/rump/rumpuser_port.h minix-comp rump
./usr/include/rump/rumpvfs_if_pub.h minix-comp rump
./usr/include/rump/rumpvnode_if.h minix-comp rump
./usr/include/rump/ukfs.h minix-comp rump
./usr/include/saslc.h minix-comp crypto
./usr/include/sched.h minix-comp
./usr/include/search.h minix-comp
@ -2458,6 +2459,7 @@
./usr/lib/libtermlib_pic.a minix-comp
./usr/lib/libtimers.a minix-comp
./usr/lib/libtimers_pic.a minix-comp
./usr/lib/libukfs.a minix-comp rump
./usr/lib/libusb.a minix-comp
./usr/lib/libusb_pic.a minix-comp
./usr/lib/libutil.a minix-comp

View File

@ -3070,6 +3070,7 @@
./usr/man/man3/tzsetwall.3 minix-man
./usr/man/man3/ualarm.3 minix-man
./usr/man/man3/uid_from_user.3 minix-man
./usr/man/man3/ukfs.3 minix-man rump
./usr/man/man3/ulimit.3 minix-man
./usr/man/man3/uname.3 minix-man
./usr/man/man3/unctrl.3 minix-man

View File

@ -307,7 +307,7 @@ SUBDIR+= ../external/bsd/mdocml/lib
#==================== 4th library dependency barrier ====================
SUBDIR+= .WAIT
#SUBDIR+= libukfs # depends on librumpvfs, librump
SUBDIR+= libukfs # depends on librumpvfs, librump
.if (${MKTPM} != "no")
SUBDIR+= ../crypto/external/cpl/trousers/lib

26
lib/libukfs/Makefile Normal file
View File

@ -0,0 +1,26 @@
# $NetBSD: Makefile,v 1.7 2013/09/11 23:04:11 joerg Exp $
#
WARNS= 2
LIB= ukfs
.if defined(__MINIX)
LIBDPLIBS+= rump ${.CURDIR}/../librump \
rumpvfs ${.CURDIR}/../librumpvfs \
mthread ${.CURDIR}/../../minix/lib/libmthread
CPPFLAGS+= -Wno-unused-function
.else
LIBDPLIBS+= rump ${.CURDIR}/../librump \
rumpvfs ${.CURDIR}/../librumpvfs \
pthread ${.CURDIR}/../libpthread
.endif # defined(__MINIX)
CPPFLAGS+= -I${.CURDIR}
INCS= ukfs.h
INCSDIR= /usr/include/rump
SRCS= ukfs.c ukfs_disklabel.c
MAN= ukfs.3
.include <bsd.lib.mk>

View File

@ -0,0 +1,4 @@
# $NetBSD: shlib_version,v 1.2 2009/01/11 02:47:19 christos Exp $
#
major=1
minor=0

321
lib/libukfs/ukfs.3 Normal file
View File

@ -0,0 +1,321 @@
.\" $NetBSD: ukfs.3,v 1.14 2014/02/14 07:27:37 wiz 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 February 13, 2014
.Dt UKFS 3
.Os
.Sh NAME
.Nm ukfs
.Nd user kernel file system library interface
.Sh LIBRARY
ukfs Library (libukfs, \-lukfs)
.Sh SYNOPSIS
.In rump/ukfs.h
.Sh DESCRIPTION
The
.Nm
library provides direct access to file systems without having to
specially mount a file system.
Therefore, accessing a file system through
.Nm
requires no special kernel support apart from standard POSIX functionality.
As
.Nm
is built upon
.Xr rump 3
kernels, all kernel file systems which are supported by rump kernels
are available.
It allows to write utilities for accessing file systems
without having to duplicate file system internals knowledge already
present in kernel file system drivers.
.Pp
.Nm
provides a high-level pathname based interface for accessing file systems.
If a lower level interface it desired,
.Xr rump 3
kernels should be used directly.
However, much like system calls, the interfaces of
.Nm ,
are self-contained and require no tracking and release of resources.
The only exception is the file system handle
.Ft struct ukfs
which should be released after use.
.Sh INITIALIZATION
.Bl -ohang
.It Ft int
.Fn ukfs_init
.It Ft int
.Fn ukfs_modload "const char *fname"
.It Ft int
.Fn ukfs_modload_dir "const char *dirname"
.It Ft ssize_t
.Fn ukfs_vfstypes "char *buf" "size_t buflen"
.It Ft struct ukfs *
.Fn ukfs_mount "const char *vfsname" "const char *devpath" \
"const char *mountpath" "int mntflags" "void *arg" "size_t alen"
.It Ft struct ukfs *
.Fn ukfs_mount_disk "const char *vfsname" "const char *devpath" \
"int partition" "const char *mountpath" "int mntflags" \
"void *arg" "size_t alen"
.It Ft int
.Fn ukfs_release "struct ukfs *ukfs" "int flags"
.El
.Pp
.Fn ukfs_init
intializes the library and must be called once per process using
.Nm .
.Pp
.Fn ukfs_modload
is used at runtime to dynamically load a library which contains a
file system module.
For this to succeed, the
.Xr rump 3
kernel and the module targetted must be compiled with compatible kernel
versions and the application must be dynamically linked.
Additionally, since this routine does not handle dependencies, all the
dependencies of the library must be loaded beforehand.
The routine returns \-1 for fatal error, 0 for dependency failure and 1
for success.
.Pp
.Fn ukfs_modload_dir
loads all
.Xr rump 3
kernel file system components in directory
.Fa dirname .
It looks for libraries which begin with
.Pa librumpfs_
and end in
.Pa .so .
The routine tries to handle dependencies by retrying to load libraries
which failed due to dependencies.
.Fn ukfs_modload_dir
returns the number of vfs modules loaded or sets errno and
returns \-1 in case of a fatal error in directory searching.
In case a fatal error occurs after some modules have already been
loaded, the number of loaded module is returned.
Fatal errors in loading the modules themselves are ignored and
.Fn ukfs_modload
should be used directly if finegrained error reporting is desired.
.Pp
It should be noted that the above routines affect the whole process,
not just a specific instance of
.Nm .
It is preferable to call them from only one thread, as the underlying
dynamic library interfaces may not be threadsafe.
.Pp
.Fn ukfs_vfstypes
queries the available file system types and returns a nul-terminated
list of types separated by spaces in
.Fa buf .
The format of the list is equivalent to the one returned by
.Xr sysctl 3
on the name
.Pa vfs.generic.fstypes .
The function returns the length of the string without the trailing nul
or \-1 for error.
Notably, the return value 0 means there are no file systems available.
If there is not enough room in the caller's buffer for all file system
types, as many as fit will be returned.
.Pp
.Fn ukfs_mount
intializes a file system image.
The handle resulting from the operation is passed to all other routines
and identifies the instance of the mount analoguous to what a pathname
specifies in a normally mounted file system.
The parameters are the following:
.Bl -tag -width XXX -offset indent
.It vfsname
Name of the file system to be used, e.g.
.Dv MOUNT_FFS .
.It devpath
Path of file system image.
It can be either a regular file, device or, if the file system does
not support the concept of a device, an abitrary string, e.g. network
address.
.It mountpath
Path where the file system is mounted to.
This parameter is used only by the file system being mounted.
Most of the time
.Dv UKFS_DEFAULTMP
is the correct path.
.It mntflags
Flags as passed to the
.Xr mount 2
system call, for example
.Dv MNT_RDONLY .
In addition to generic parameters, file system specific parameters such as
.Dv MNT_LOG
(ffs) may be passed here.
.It arg
File system private argument structure.
This is passed directly to the file system.
It must match what
.Fa vfsname
expects.
.It alen
Size of said structure.
.El
.Pp
The
.Fn ukfs_mount_disk
function must be used to mount disk-based file systems.
It takes the same arguments as
.Fn ukfs_mount ,
except for an additional argument signifying the
.Fa partition
number.
If the image
.Fa devpath
contains a disklabel, this value specifies the number of the partition
within the image used as the file system backend.
If
.Fa devpath
does not contain a disklabel, the value
.Dv UKFS_PARTITION_NONE
must be used to signal that the file system backend is the entire
image.
.Pp
.Fn ukfs_release
unmounts the file system and releases the resources associated with
.Fa ukfs .
The return value signals the return value of the unmount operation.
If non-zero,
.Fa ukfs
will continue to remain valid.
The possible values for flags are:
.Bl -tag -width XUKFS_RELFLAG_NOUNMOUT -offset indent
.It Dv UKFS_RELFLAG_NOUNMOUNT
Do not unmount file system, just release ukfs handle.
Release always succeeds.
.It Dv UKFS_RELFLAG_FORCE
Forcefully unmount the file system.
This means that any busy nodes (due to e.g.
.Fn ukfs_chdir )
will be ignored.
Release always succeeds.
.El
.Sh OPERATION
.Bl -ohang
.It Ft int
.Fn ukfs_chdir "struct ukfs *ukfs" "const char *path"
.It Ft int
.Fn ukfs_getdents "struct ukfs *ukfs" "const char *dirname" "off_t *off" \
"uint8_t *buf" "size_t bufsize"
.It Ft ssize_t
.Fn ukfs_read "struct ukfs *ukfs" "const char *filename" "off_t off" \
"uint8_t *buf" "size_t bufsize"
.It Ft ssize_t
.Fn ukfs_write "struct ukfs *ukfs" "const char *filename" "off_t off" \
"uint8_t *buf" "size_t bufsize"
.It Ft int
.Fn ukfs_create "struct ukfs *ukfs" "const char *filename" "mode_t mode"
.It Ft int
.Fn ukfs_mknod "struct ukfs *ukfs" "const char *path" "mode_t mode" "dev_t dev"
.It Ft int
.Fn ukfs_mkfifo "struct ukfs *ukfs" "const char *path" "mode_t mode"
.It Ft int
.Fn ukfs_mkdir "struct ukfs *ukfs" "const char *filename" "mode_t mode"
.It Ft int
.Fn ukfs_remove "struct ukfs *ukfs" "const char *filename"
.It Ft int
.Fn ukfs_rmdir "struct ukfs *ukfs" "const char *filename"
.It Ft int
.Fn ukfs_link "struct ukfs *ukfs" "const char *filename" "const char *f_create"
.It Ft int
.Fn ukfs_symlink "struct ukfs *ukfs" "const char *filename" \
"const char *linkname"
.It Ft ssize_t
.Fn ukfs_readlink "struct ukfs *ukfs" "const char *filename" \
"char *linkbuf" "size_t buflen"
.It Ft int
.Fn ukfs_rename "struct ukfs *ukfs" "const char *from" "const char *to"
.It Ft int
.Fn ukfs_stat "struct ukfs *ukfs" "const char *filename" \
"struct stat *file_stat"
.It Ft int
.Fn ukfs_lstat "struct ukfs *ukfs" "const char *filename" \
"struct stat *file_stat"
.It Ft int
.Fn ukfs_chmod "struct ukfs *ukfs" "const char *filename" "mode_t mode"
.It Ft int
.Fn ukfs_lchmod "struct ukfs *ukfs" "const char *filename" "mode_t mode"
.It Ft int
.Fn ukfs_chown "struct ukfs *ukfs" "const char *filename" "uid_t uid" \
"gid_t gid"
.It Ft int
.Fn ukfs_lchown "struct ukfs *ukfs" "const char *filename" "uid_t uid" \
"gid_t gid"
.It Ft int
.Fn ukfs_chflags "struct ukfs *ukfs" "const char *filename" "u_long flags"
.It Ft int
.Fn ukfs_lchflags "struct ukfs *ukfs" "const char *filename" "u_long flags"
.It Ft int
.Fn ukfs_utimes "struct ukfs *ukfs" "const char *filename" \
"const struct timeval *tptr"
.It Ft int
.Fn ukfs_lutimes "struct ukfs *ukfs" "const char *filename" \
"const struct timeval *tptr"
.El
.Pp
The above routines operate like their system call counterparts and the
system call manual pages without the ukfs_ prefix should be referred to
for further information on the parameters.
.Pp
The only call which modifies
.Fa ukfs
state is
.Fn ukfs_chdir .
It works like
.Xr chdir 2
in the sense that it affects the interpretation of relative paths.
If succesful, all relative pathnames will be resolved starting from the
current directory.
Currently the call affects all accesses to that particular
.Fa ukfs ,
but it might be later changed to be thread private.
.Sh UTILITIES
.Bl -ohang
.It Ft int
.Fn ukfs_util_builddirs "struct ukfs *ukfs" "const char *pathname" "mode_t mode"
.El
.Pp
Builds a directory hierarchy.
Unlike mkdir, the
.Fa pathname
argument may contain multiple levels of hierarchy.
It is not considered an error if any of the directories specified exist
already.
.Sh SEE ALSO
.Xr rump 3
.Sh HISTORY
.Nm
first appeared in
.Nx 5.0 .
.Sh AUTHORS
.An Antti Kantee Aq Mt pooka@cs.hut.fi
.Sh NOTES
.Nm
was an early attempt at an interface for kernel file systems
running in userspace.

1379
lib/libukfs/ukfs.c Normal file

File diff suppressed because it is too large Load Diff

153
lib/libukfs/ukfs.h Normal file
View File

@ -0,0 +1,153 @@
/* $NetBSD: ukfs.h,v 1.14 2012/07/19 06:33:03 joerg Exp $ */
/*
* Copyright (c) 2007, 2008, 2009 Antti Kantee. All Rights Reserved.
*
* Development of this software was supported by the
* Finnish Cultural Foundation.
*
* 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 _RUMP_UKFS_H_
#define _RUMP_UKFS_H_
#include <sys/types.h>
#include <stdint.h>
/* don't include NetBSD <sys/header.h> for portability */
struct vnode;
struct stat;
struct timeval;
struct ukfs;
struct ukfs_dircookie;
struct ukfs_part;
#define UKFS_DEFAULTMP "/ukfs"
#define UKFS_RELFLAG_NOUNMOUNT 0x01
#define UKFS_RELFLAG_FORCE 0x02
#define UKFS_VERSION 002 /* secret ukfs 002 */
#define ukfs_init() _ukfs_init(UKFS_VERSION)
__BEGIN_DECLS
int _ukfs_init(int);
struct ukfs *ukfs_mount(const char *, const char *, const char *,
int, void *, size_t);
struct ukfs *ukfs_mount_disk(const char *, const char *, struct ukfs_part *,
const char *, int, void *, size_t);
int ukfs_release(struct ukfs *, int);
int ukfs_opendir(struct ukfs *, const char *,
struct ukfs_dircookie **);
int ukfs_getdents(struct ukfs *, const char *, off_t *,
uint8_t *, size_t);
int ukfs_getdents_cookie(struct ukfs *, struct ukfs_dircookie *,
off_t *, uint8_t *, size_t);
int ukfs_closedir(struct ukfs *, struct ukfs_dircookie *);
int ukfs_open(struct ukfs *, const char *, int);
ssize_t ukfs_read(struct ukfs *, const char *, off_t,
uint8_t *, size_t);
ssize_t ukfs_read_fd(struct ukfs *, int, off_t, uint8_t *, size_t);
ssize_t ukfs_write(struct ukfs *, const char *, off_t,
uint8_t *, size_t);
ssize_t ukfs_write_fd(struct ukfs *, int, off_t, uint8_t *, size_t,int);
int ukfs_close(struct ukfs *, int);
ssize_t ukfs_readlink(struct ukfs *, const char *, char *, size_t);
int ukfs_create(struct ukfs *, const char *, mode_t);
int ukfs_mkdir(struct ukfs *, const char *, mode_t);
int ukfs_mknod(struct ukfs *, const char *, mode_t, dev_t);
int ukfs_mkfifo(struct ukfs *, const char *, mode_t);
int ukfs_symlink(struct ukfs *, const char *, const char *);
int ukfs_remove(struct ukfs *, const char *);
int ukfs_rmdir(struct ukfs *, const char *);
int ukfs_link(struct ukfs *, const char *, const char *);
int ukfs_rename(struct ukfs *, const char *, const char *);
int ukfs_chdir(struct ukfs *, const char *);
int ukfs_stat(struct ukfs *, const char *, struct stat *);
int ukfs_lstat(struct ukfs *, const char *, struct stat *);
int ukfs_chmod(struct ukfs *, const char *, mode_t);
int ukfs_lchmod(struct ukfs *, const char *, mode_t);
int ukfs_chown(struct ukfs *, const char *, uid_t, gid_t);
int ukfs_lchown(struct ukfs *, const char *, uid_t, gid_t);
int ukfs_chflags(struct ukfs *, const char *, u_long);
int ukfs_lchflags(struct ukfs *, const char *, u_long);
int ukfs_utimes(struct ukfs *, const char *,
const struct timeval *);
int ukfs_lutimes(struct ukfs *, const char *,
const struct timeval *);
struct mount *ukfs_getmp(struct ukfs *);
struct vnode *ukfs_getrvp(struct ukfs *);
void ukfs_setspecific(struct ukfs *, void *);
void * ukfs_getspecific(struct ukfs *);
/* partition magic in device names */
extern struct ukfs_part *ukfs_part_none;
extern struct ukfs_part *ukfs_part_na;
#define UKFS_PARTITION_SCANMAGIC "%PART:" /* deprecated */
#define UKFS_DISKLABEL_SCANMAGIC "%DISKLABEL:"
#define UKFS_DISKLABEL_MAGICLEN (sizeof(UKFS_DISKLABEL_SCANMAGIC "a%")-1)
#define UKFS_OFFSET_SCANMAGIC "%OFFSET:"
#define UKFS_OFFSET_MINLEN (sizeof(UKFS_OFFSET_SCANMAGIC "512,512%")-1)
#define UKFS_DEVICE_MAXSTR 128 /* unexact science ... */
#define UKFS_DEVICE_MAXPATHLEN (MAXPATHLEN+UKFS_DEVICE_MAXSTR)
#define UKFS_DEVICE_ARGVPROBE(part) \
do { \
if (argc < 3) \
*part = NULL; \
else if (ukfs_part_probe(argv[argc-2], part) == -1) \
err(1, "ukfs_part_probe"); \
} while (/*CONSTCOND*/0)
int ukfs_part_probe(char *, struct ukfs_part **);
void ukfs_part_release(struct ukfs_part *);
int ukfs_part_tostring(struct ukfs_part *, char *, size_t);
/* dynamic loading of library modules */
int ukfs_modload(const char *);
int ukfs_modload_dir(const char *);
ssize_t ukfs_vfstypes(char *, size_t);
/* Utilities */
int ukfs_util_builddirs(struct ukfs *, const char *, mode_t);
__END_DECLS
#endif /* _RUMP_UKFS_H_ */

View File

@ -0,0 +1,150 @@
/* $NetBSD: ukfs_disklabel.c,v 1.3 2011/02/22 15:42:15 pooka Exp $ */
/*
* Local copies of libutil disklabel routines. This uncouples libukfs
* from the NetBSD-only libutil. All identifiers are prefixed with
* ukfs or UKFS, otherwise the routines are the same.
*/
/*
* From:
* NetBSD: disklabel_scan.c,v 1.3 2009/01/18 12:13:03 lukem Exp
*/
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Roland C. Dowdeswell.
*
* 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/types.h>
#include <string.h>
#include <unistd.h>
#include "ukfs_int_disklabel.h"
#define SCAN_INCR 4
int
ukfs__disklabel_scan(struct ukfs__disklabel *lp, int *isswapped,
char *buf, size_t buflen)
{
size_t i;
int imswapped;
uint16_t npart;
/* scan for the correct magic numbers. */
for (i=0; i <= buflen - sizeof(*lp); i += SCAN_INCR) {
memcpy(lp, buf + i, sizeof(*lp));
if (lp->d_magic == UKFS_DISKMAGIC &&
lp->d_magic2 == UKFS_DISKMAGIC) {
imswapped = 0;
goto sanity;
}
if (lp->d_magic == bswap32(UKFS_DISKMAGIC) &&
lp->d_magic2 == bswap32(UKFS_DISKMAGIC)) {
imswapped = 1;
goto sanity;
}
}
return 1;
sanity:
if (imswapped)
npart = bswap16(lp->d_npartitions);
else
npart = lp->d_npartitions;
/* we've found something, let's sanity check it */
if (npart > UKFS_MAXPARTITIONS
|| ukfs__disklabel_dkcksum(lp, imswapped))
return 1;
*isswapped = imswapped;
return 0;
}
/*
* From:
* $NetBSD: disklabel_dkcksum.c,v 1.4 2005/05/15 21:01:34 thorpej Exp
*/
/*-
* Copyright (c) 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.
*/
uint16_t
ukfs__disklabel_dkcksum(struct ukfs__disklabel *lp, int imswapped)
{
uint16_t *start, *end;
uint16_t sum;
uint16_t npart;
if (imswapped)
npart = bswap16(lp->d_npartitions);
else
npart = lp->d_npartitions;
sum = 0;
start = (uint16_t *)(void *)lp;
end = (uint16_t *)(void *)&lp->d_partitions[npart];
while (start < end) {
if (imswapped)
sum ^= bswap16(*start);
else
sum ^= *start;
start++;
}
return (sum);
}

View File

@ -0,0 +1,158 @@
/* $NetBSD: ukfs_int_disklabel.h,v 1.3 2011/02/22 15:42:15 pooka Exp $ */
/*
* Modified copy of disklabel.h so that ukfs doesn't have to depend
* on NetBSD headers. Contains just about only "struct disklabel".
* The on-disk disklabel doesn't really change format, so no need
* to track this against NetBSD changes.
*/
/*
* Copyright (c) 1987, 1988, 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.
*
* @(#)disklabel.h 8.2 (Berkeley) 7/10/94
*/
#ifndef LIB_UKFS_DISKLABEL_H_
#define LIB_UKFS_DISKLABEL_H_
#include <sys/types.h>
#include <stdint.h>
#define UKFS_MAXPARTITIONS 22
#define UKFS_DISKMAGIC ((uint32_t)0x82564557) /* The disk magic number */
struct ukfs__disklabel {
uint32_t d_magic; /* the magic number */
uint16_t d_type; /* drive type */
uint16_t d_subtype; /* controller/d_type specific */
char d_typename[16]; /* type name, e.g. "eagle" */
/*
* d_packname contains the pack identifier and is returned when
* the disklabel is read off the disk or in-core copy.
* d_boot0 and d_boot1 are the (optional) names of the
* primary (block 0) and secondary (block 1-15) bootstraps
* as found in /usr/mdec. These are returned when using
* getdiskbyname(3) to retrieve the values from /etc/disktab.
*/
union {
char un_d_packname[16]; /* pack identifier */
struct {
char *un_d_boot0; /* primary bootstrap name */
char *un_d_boot1; /* secondary bootstrap name */
} un_b;
} d_un;
#define d_packname d_un.un_d_packname
#define d_boot0 d_un.un_b.un_d_boot0
#define d_boot1 d_un.un_b.un_d_boot1
/* disk geometry: */
uint32_t d_secsize; /* # of bytes per sector */
uint32_t d_nsectors; /* # of data sectors per track */
uint32_t d_ntracks; /* # of tracks per cylinder */
uint32_t d_ncylinders; /* # of data cylinders per unit */
uint32_t d_secpercyl; /* # of data sectors per cylinder */
uint32_t d_secperunit; /* # of data sectors per unit */
/*
* Spares (bad sector replacements) below are not counted in
* d_nsectors or d_secpercyl. Spare sectors are assumed to
* be physical sectors which occupy space at the end of each
* track and/or cylinder.
*/
uint16_t d_sparespertrack; /* # of spare sectors per track */
uint16_t d_sparespercyl; /* # of spare sectors per cylinder */
/*
* Alternative cylinders include maintenance, replacement,
* configuration description areas, etc.
*/
uint32_t d_acylinders; /* # of alt. cylinders per unit */
/* hardware characteristics: */
/*
* d_interleave, d_trackskew and d_cylskew describe perturbations
* in the media format used to compensate for a slow controller.
* Interleave is physical sector interleave, set up by the
* formatter or controller when formatting. When interleaving is
* in use, logically adjacent sectors are not physically
* contiguous, but instead are separated by some number of
* sectors. It is specified as the ratio of physical sectors
* traversed per logical sector. Thus an interleave of 1:1
* implies contiguous layout, while 2:1 implies that logical
* sector 0 is separated by one sector from logical sector 1.
* d_trackskew is the offset of sector 0 on track N relative to
* sector 0 on track N-1 on the same cylinder. Finally, d_cylskew
* is the offset of sector 0 on cylinder N relative to sector 0
* on cylinder N-1.
*/
uint16_t d_rpm; /* rotational speed */
uint16_t d_interleave; /* hardware sector interleave */
uint16_t d_trackskew; /* sector 0 skew, per track */
uint16_t d_cylskew; /* sector 0 skew, per cylinder */
uint32_t d_headswitch; /* head switch time, usec */
uint32_t d_trkseek; /* track-to-track seek, usec */
uint32_t d_flags; /* generic flags */
#define NDDATA 5
uint32_t d_drivedata[NDDATA]; /* drive-type specific information */
#define NSPARE 5
uint32_t d_spare[NSPARE]; /* reserved for future use */
uint32_t d_magic2; /* the magic number (again) */
uint16_t d_checksum; /* xor of data incl. partitions */
/* filesystem and partition information: */
uint16_t d_npartitions; /* number of partitions in following */
uint32_t d_bbsize; /* size of boot area at sn0, bytes */
uint32_t d_sbsize; /* max size of fs superblock, bytes */
struct ukfs__partition { /* the partition table */
uint32_t p_size; /* number of sectors in partition */
uint32_t p_offset; /* starting sector */
union {
uint32_t fsize; /* FFS, ADOS:
filesystem basic fragment size */
uint32_t cdsession; /* ISO9660: session offset */
} __partition_u2;
#define p_fsize __partition_u2.fsize
#define p_cdsession __partition_u2.cdsession
uint8_t p_fstype; /* filesystem type, see below */
uint8_t p_frag; /* filesystem fragments per block */
union {
uint16_t cpg; /* UFS: FS cylinders per group */
uint16_t sgs; /* LFS: FS segment shift */
} __partition_u1;
#define p_cpg __partition_u1.cpg
#define p_sgs __partition_u1.sgs
} d_partitions[UKFS_MAXPARTITIONS]; /* actually may be more */
};
uint16_t ukfs__disklabel_dkcksum(struct ukfs__disklabel *, int);
int ukfs__disklabel_scan(struct ukfs__disklabel *, int *,
char *, size_t);
#endif /* !LIB_UKFS_DISKLABEL_H_ */