/*-
* Copyright (c) 2007 Doug Rabson
* 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
*
* 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.
*
* $FreeBSD$
*/
/*
* Stand-alone file reading package.
*/
#include <part.h>
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <stand.h>
#include <bootstrap.h>
#include "libzfs.h"
#include "zfsimpl.c"
/* Define the range of indexes to be populated with ZFS Boot Environments */
"zfs",
};
/*
* In-core open file.
*/
struct file {
};
#ifdef __FreeBSD__
static int zfs_env_index;
static int zfs_env_count;
#endif
struct zfs_be_entry {
const char *name;
/*
* Open a file.
*/
static int
{
int rc;
return (EINVAL);
/* allocate file system specific data structure */
if (rc) {
}
return (rc);
}
static int
{
dnode_cache_obj = 0;
f->f_fsdata = (void *)0;
return (0);
return (0);
}
/*
* Copy a portion of a file into kernel memory.
* Cross block boundaries when necessary.
*/
static int
{
size_t n;
int rc;
if (rc)
return (rc);
n = size;
if (rc)
return (rc);
if (0) {
int i;
for (i = 0; i < n; i++)
}
if (resid)
return (0);
}
/*
* Don't be silly - the bootstrap has no business writing anything.
*/
static int
{
return (EROFS);
}
static off_t
{
switch (where) {
case SEEK_SET:
break;
case SEEK_CUR:
break;
case SEEK_END:
{
int error;
if (error != 0) {
return (-1);
}
break;
}
default:
return (-1);
}
}
static int
{
}
static int
{
int rc;
if (rc)
return (rc);
return (ENOTDIR);
/*
* If this is the first read, get the zap type.
*/
if (rc)
return (rc);
} else {
&fp->f_num_leafs,
sizeof(fp->f_num_leafs));
if (rc)
return (rc);
fp->f_zap_leaf,
bsize);
if (rc)
return (rc);
}
}
return (ENOENT);
if (rc)
return (rc);
goto mzap_next;
return (0);
} else {
int chunk;
char *p;
/*
* Initialise this so we can use the ZAP size
* calculating macros.
*/
/*
* Figure out which chunk we are currently looking at
* and consider seeking to the next leaf. We use the
* low bits of f_seekp as a simple chunk index.
*/
chunk = 0;
/*
* Check for EOF and read the new leaf.
*/
return (ENOENT);
fp->f_zap_leaf,
bsize);
if (rc)
return (rc);
}
goto fzap_next;
/*
* Paste the name back together.
*/
p = d->d_name;
while (namelen > 0) {
int len;
if (len > ZAP_LEAF_ARRAY_BYTES)
p += len;
}
/*
* Assume the first eight bytes of the value are
* a uint64_t.
*/
return (0);
}
}
static int
{
int fd;
return 0;
} else {
return (EIO);
}
}
static int
zfs_dev_init(void)
{
zfs_init();
return (ENXIO);
if (zfs_spa_init(spa)) {
else
} else
}
return (0);
}
struct zfs_probe_args {
int fd;
const char *devname;
};
static int
{
}
static int
{
int ret;
return (ret);
}
static int
const struct ptable_entry *part)
{
int ret = 0;
/* filter out partitions *not* used by zfs */
case PART_RESERVED: /* efi reserverd */
case PART_VTOC_BOOT: /* vtoc boot area */
case PART_VTOC_SWAP:
return (ret);
default:
break;;
}
return (ret);
if (ret == 0)
return (ret);
}
}
return (0);
}
int
{
int ret;
return (ENXIO);
/* Probe the whole disk */
if (ret == 0)
return (0);
/* Probe each partition */
if (ret == 0)
if (ret == 0) {
}
}
return (ret);
}
/*
* Print information about ZFS pools
*/
static int
{
int ret = 0;
if (verbose) {
return (spa_all_status());
}
if (ret != 0)
break;
}
return (ret);
}
/*
* Attempt to open the pool described by (dev) for use by (f).
*/
static int
{
int rv;
else
if (!spa)
return (ENXIO);
if (rv != 0) {
return (rv);
}
printf("Unexpected object set type %ju\n",
return (EIO);
}
return (0);
}
static int
{
return (0);
}
static int
{
return (ENOSYS);
}
.dv_name = "zfs",
.dv_init = zfs_dev_init,
.dv_open = zfs_dev_open,
.dv_cleanup = NULL
};
int
{
const char *end;
const char *np;
const char *sep;
int rv;
if (*np != ':')
return (EINVAL);
np++;
return (EINVAL);
sep++;
}
else
rootname[0] = '\0';
if (!spa)
return (ENXIO);
if (rv != 0)
return (rv);
return (0);
}
char *
{
int n;
buf[0] = '\0';
return (buf);
printf("ZFS: can't find pool by guid\n");
return (buf);
}
printf("ZFS: can't find filesystem by guid\n");
return (buf);
}
printf("ZFS: can't find filesystem by name\n");
return (buf);
}
/* use this kid? */
break;
}
break;
}
break;
}
/*
* since this pool was used to read in the kernel and boot archive,
* there has to be at least one healthy vdev, therefore vdev
* can not be NULL.
*/
(unsigned long long)objnum);
}
}
return (buf);
}
char *
{
buf[0] = '\0';
return (buf);
} else
printf("ZFS: can't find pool by guid\n");
return (buf);
}
printf("ZFS: can't find root filesystem\n");
return (buf);
}
printf("ZFS: can't find filesystem by guid\n");
return (buf);
}
if (rootname[0] == '\0')
else
rootname);
return (buf);
}
int
{
const char *dsname;
int len;
int rv;
dsname++;
} else
dsname = "";
if (!spa)
return (ENXIO);
if (rv != 0)
return (rv);
}
#ifdef __FreeBSD__
void
{
char *beroot;
return;
return;
/* Remove the trailing : */
/* Forward past zfs: */
currdev++;
/* Remove the last element (current bootenv) */
beroot[0] = '\0';
}
int
{
return (EINVAL);
return (EINVAL);
return (ENOMEM);
}
zfs_env_count = 0;
dsname++;
} else
dsname = "";
if (!spa)
return (ENXIO);
if (rv != 0)
return (rv);
/* Calculate and store the number of pages of BEs */
return (ENOMEM);
/* Roll over the page counter if it has exceeded the maximum */
return (ENOMEM);
}
/* Populate the menu environment variables */
zfs_set_env();
/* Clean up the SLIST of ZFS BEs */
while (!SLIST_EMPTY(&zfs_be_head)) {
}
return (rv);
}
int
{
/* Skip special datasets that start with a $ character */
return (0);
}
/* Add the boot environment to the head of the SLIST */
return (ENOMEM);
}
return (0);
}
int
zfs_set_env(void)
{
return (1);
}
} else {
page = 1;
}
ctr = 1;
rv = 0;
/* Skip to the requested page number */
ctr++;
continue;
}
if (rv != 0) {
break;
}
if (rv != 0){
break;
}
if (rv != 0){
break;
}
if (rv != 0){
break;
}
if (zfs_env_index > ZFS_BE_LAST) {
break;
}
}
}
return (rv);
}
#endif