Page MenuHomeFreeBSD

D18564.id56370.diff
No OneTemporary

D18564.id56370.diff

Index: etc/mtree/BSD.tests.dist
===================================================================
--- etc/mtree/BSD.tests.dist
+++ etc/mtree/BSD.tests.dist
@@ -280,6 +280,8 @@
..
libarchive
..
+ libbe
+ ..
libc
c063
..
Index: lib/libbe/Makefile
===================================================================
--- lib/libbe/Makefile
+++ lib/libbe/Makefile
@@ -1,8 +1,10 @@
# $FreeBSD$
+.include <src.opts.mk>
+
PACKAGE= lib${LIB}
LIB= be
-SHLIBDIR?= /lib
+SHLIBDIR= /lib
SHLIB_MAJOR= 1
SHLIB_MINOR= 0
@@ -28,4 +30,7 @@
CFLAGS+= -DNEED_SOLARIS_BOOLEAN
+HAS_TESTS= YES
+SUBDIR.${MK_TESTS}+= tests
+
.include <bsd.lib.mk>
Index: lib/libbe/be.h
===================================================================
--- lib/libbe/be.h
+++ lib/libbe/be.h
@@ -84,6 +84,8 @@
/* Bootenv creation functions */
int be_create(libbe_handle_t *, const char *);
+int be_create_depth(libbe_handle_t *, const char *, const char *, int);
+int be_create_shallow(libbe_handle_t *, const char *, const char *);
int be_create_from_existing(libbe_handle_t *, const char *, const char *);
int be_create_from_existing_snap(libbe_handle_t *, const char *, const char *);
int be_snapshot(libbe_handle_t *, const char *, const char *, bool, char *);
Index: lib/libbe/be.c
===================================================================
--- lib/libbe/be.c
+++ lib/libbe/be.c
@@ -352,7 +352,6 @@
sizeof(buf)) >= sizeof(buf))
return (set_error(lbh, BE_ERR_INVALIDNAME));
}
-
if ((err = zfs_snapshot(lbh->lzh, buf, recursive, NULL)) != 0) {
switch (err) {
case EZFS_INVALIDNAME:
@@ -426,43 +425,78 @@
return (ZPROP_CONT);
}
+/*
+ * Return the corresponding boot environment path for a given
+ * dataset path, the constructed path is placed in 'result'.
+ *
+ * example: say our new boot environment name is 'bootenv' and
+ * the dataset path is 'zroot/ROOT/default/data/set'.
+ *
+ * result should produce: 'zroot/ROOT/bootenv/data/set'
+ */
+static int
+be_get_path(struct libbe_deep_clone *ldc, const char *dspath, char *result, int result_size)
+{
+ char *pos;
+ char *child_dataset;
+
+ /* match the root path for the boot environments */
+ pos = strstr(dspath, ldc->lbh->root);
+
+ /* no match, different pools? */
+ if (pos == NULL)
+ return (BE_ERR_BADPATH);
+
+ /* root path of the new boot environment */
+ snprintf(result, result_size, "%s/%s", ldc->lbh->root, ldc->bename);
+
+ /* gets us to the parent dataset, the +1 consumes a trailing slash */
+ pos += strlen(ldc->lbh->root) + 1;
+
+ /* skip the parent dataset */
+ if ((child_dataset = strchr(pos, '/')) != NULL)
+ strlcat(result, child_dataset, result_size);
+
+ return (BE_ERR_SUCCESS);
+}
+
static int
-be_deep_clone(zfs_handle_t *ds, void *data)
+be_clone_cb(zfs_handle_t *ds, void *data)
{
int err;
char be_path[BE_MAXPATHLEN];
char snap_path[BE_MAXPATHLEN];
const char *dspath;
- char *dsname;
zfs_handle_t *snap_hdl;
nvlist_t *props;
- struct libbe_deep_clone *isdc, sdc;
+ struct libbe_deep_clone *ldc;
struct libbe_dccb dccb;
- isdc = (struct libbe_deep_clone *)data;
+ ldc = (struct libbe_deep_clone *)data;
dspath = zfs_get_name(ds);
- if ((dsname = strrchr(dspath, '/')) == NULL)
- return (BE_ERR_UNKNOWN);
- dsname++;
- if (isdc->bename == NULL)
- snprintf(be_path, sizeof(be_path), "%s/%s", isdc->be_root, dsname);
- else
- snprintf(be_path, sizeof(be_path), "%s/%s", isdc->be_root, isdc->bename);
+ snprintf(snap_path, sizeof(snap_path), "%s@%s", dspath, ldc->snapname);
- snprintf(snap_path, sizeof(snap_path), "%s@%s", dspath, isdc->snapname);
+ /* construct the boot environment path from the dataset we're cloning */
+ if (be_get_path(ldc, dspath, be_path, sizeof(be_path)) != BE_ERR_SUCCESS)
+ return (set_error(ldc->lbh, BE_ERR_UNKNOWN));
- if (zfs_dataset_exists(isdc->lbh->lzh, be_path, ZFS_TYPE_DATASET))
- return (set_error(isdc->lbh, BE_ERR_EXISTS));
+ /* the dataset to be created (i.e. the boot environment) already exists */
+ if (zfs_dataset_exists(ldc->lbh->lzh, be_path, ZFS_TYPE_DATASET))
+ return (set_error(ldc->lbh, BE_ERR_EXISTS));
+
+ /* no snapshot found for this dataset, silently skip it */
+ if (!zfs_dataset_exists(ldc->lbh->lzh, snap_path, ZFS_TYPE_SNAPSHOT))
+ return (0);
if ((snap_hdl =
- zfs_open(isdc->lbh->lzh, snap_path, ZFS_TYPE_SNAPSHOT)) == NULL)
- return (set_error(isdc->lbh, BE_ERR_ZFSOPEN));
+ zfs_open(ldc->lbh->lzh, snap_path, ZFS_TYPE_SNAPSHOT)) == NULL)
+ return (set_error(ldc->lbh, BE_ERR_ZFSOPEN));
nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP);
nvlist_add_string(props, "canmount", "noauto");
- dccb.lbh = isdc->lbh;
+ dccb.lbh = ldc->lbh;
dccb.zhp = ds;
dccb.props = props;
if (zprop_iter(be_deep_clone_prop, &dccb, B_FALSE, B_FALSE,
@@ -470,58 +504,55 @@
return (-1);
if ((err = zfs_clone(snap_hdl, be_path, props)) != 0)
- err = BE_ERR_ZFSCLONE;
+ return (set_error(ldc->lbh, BE_ERR_ZFSCLONE));
nvlist_free(props);
zfs_close(snap_hdl);
- /* Failed to clone */
- if (err != BE_ERR_SUCCESS)
- return (set_error(isdc->lbh, err));
-
- sdc.lbh = isdc->lbh;
- sdc.bename = NULL;
- sdc.snapname = isdc->snapname;
- sdc.be_root = (char *)&be_path;
-
- err = zfs_iter_filesystems(ds, be_deep_clone, &sdc);
+ if (ldc->depth_limit == -1 || ldc->depth < ldc->depth_limit) {
+ ldc->depth++;
+ err = zfs_iter_filesystems(ds, be_clone_cb, ldc);
+ ldc->depth--;
+ }
- return (err);
+ return (set_error(ldc->lbh, err));
}
/*
- * Create the boot environment from pre-existing snapshot
- */
-int
-be_create_from_existing_snap(libbe_handle_t *lbh, const char *name,
- const char *snap)
+ * Create a boot environment with a given name from a given snapshot.
+ * Snapshots can be in the format 'zroot/ROOT/default@snapshot' or
+ * 'default@snapshot'. In the latter case, 'default@snapshot' will be prepended
+ * with the root path that libbe was initailized with.
+*/
+static int
+be_clone(libbe_handle_t *lbh, const char *bename, const char *snapshot, int depth)
{
int err;
- char be_path[BE_MAXPATHLEN];
char snap_path[BE_MAXPATHLEN];
- const char *bename;
char *parentname, *snapname;
zfs_handle_t *parent_hdl;
- struct libbe_deep_clone sdc;
+ struct libbe_deep_clone ldc;
- if ((err = be_validate_name(lbh, name)) != 0)
- return (set_error(lbh, err));
- if ((err = be_root_concat(lbh, snap, snap_path)) != 0)
- return (set_error(lbh, err));
- if ((err = be_validate_snap(lbh, snap_path)) != 0)
+ /* ensure the boot environment name is valid */
+ if ((err = be_validate_name(lbh, bename)) != 0)
return (set_error(lbh, err));
- if ((err = be_root_concat(lbh, name, be_path)) != 0)
+ /*
+ * prepend the boot environment root path if we're
+ * given a partial snapshot name.
+ */
+ if ((err = be_root_concat(lbh, snapshot, snap_path)) != 0)
return (set_error(lbh, err));
- if ((bename = strrchr(name, '/')) == NULL)
- bename = name;
- else
- bename++;
+ /* ensure the snapshot exists */
+ if ((err = be_validate_snap(lbh, snap_path)) != 0)
+ return (set_error(lbh, err));
+ /* get a copy of the snapshot path so we can disect it */
if ((parentname = strdup(snap_path)) == NULL)
return (set_error(lbh, BE_ERR_UNKNOWN));
+ /* split dataset name from snapshot name */
snapname = strchr(parentname, '@');
if (snapname == NULL) {
free(parentname);
@@ -530,32 +561,66 @@
*snapname = '\0';
snapname++;
- sdc.lbh = lbh;
- sdc.bename = bename;
- sdc.snapname = snapname;
- sdc.be_root = lbh->root;
+ /* set-up the boot environment */
+ ldc.lbh = lbh;
+ ldc.bename = bename;
+ ldc.snapname = snapname;
+ ldc.depth = 0;
+ ldc.depth_limit = depth;
+ /* the boot environment will be cloned from this dataset */
parent_hdl = zfs_open(lbh->lzh, parentname, ZFS_TYPE_DATASET);
- err = be_deep_clone(parent_hdl, &sdc);
+
+ /* create the boot environment */
+ err = be_clone_cb(parent_hdl, &ldc);
free(parentname);
return (set_error(lbh, err));
}
+/*
+ * Create a boot environment from pre-existing snapshot, specifying a depth.
+ */
+int be_create_depth(libbe_handle_t *lbh, const char *bename,
+ const char *snap, int depth)
+{
+ return (be_clone(lbh, bename, snap, depth));
+}
+
+/*
+ * Create a non-recursive boot environment from pre-existing snapshot
+ */
+int
+be_create_shallow(libbe_handle_t *lbh, const char *bename,
+ const char *snap)
+{
+ return (be_clone(lbh, bename, snap, 0));
+}
+
+/*
+ * Create the boot environment from pre-existing snapshot
+ */
+int
+be_create_from_existing_snap(libbe_handle_t *lbh, const char *bename,
+ const char *snap)
+{
+ return (be_clone(lbh, bename, snap, -1));
+}
+
/*
* Create a boot environment from an existing boot environment
*/
int
-be_create_from_existing(libbe_handle_t *lbh, const char *name, const char *old)
+be_create_from_existing(libbe_handle_t *lbh, const char *bename, const char *old)
{
int err;
- char buf[BE_MAXPATHLEN];
+ char snap[BE_MAXPATHLEN];
- if ((err = be_snapshot(lbh, old, NULL, true, (char *)&buf)) != 0)
+ if ((err = be_snapshot(lbh, old, NULL, true, snap)) != 0)
return (set_error(lbh, err));
- err = be_create_from_existing_snap(lbh, name, (char *)buf);
+ err = be_clone(lbh, bename, snap, -1);
return (set_error(lbh, err));
}
Index: lib/libbe/be_impl.h
===================================================================
--- lib/libbe/be_impl.h
+++ lib/libbe/be_impl.h
@@ -50,7 +50,8 @@
libbe_handle_t *lbh;
const char *bename;
const char *snapname;
- const char *be_root;
+ int depth;
+ int depth_limit;
};
struct libbe_dccb {
Index: lib/libbe/libbe.3
===================================================================
--- lib/libbe/libbe.3
+++ lib/libbe/libbe.3
@@ -63,12 +63,18 @@
.Fn be_create "libbe_handle_t *hdl" "const char *be_name"
.Pp
.Ft int
+.Fn be_create_depth "libbe_handle_t *hdl" "const char *be_name" "const char *snap" "int depth"
+.Pp
+.Ft int
.Fn be_create_from_existing "libbe_handle_t *hdl" "const char *be_name" "const char *be_origin"
.Pp
.Ft int
.Fn be_create_from_existing_snap "libbe_handle_t *hdl" "const char *be_name" "const char *snap"
.Pp
.Ft int
+.Fn be_create_shallow "libbe_handle_t *hdl" "const char *be_name" "const char *snap"
+.Pp
+.Ft int
.Fn be_rename "libbe_handle_t *hdl" "const char *be_old" "const char *be_new"
.Pp
.Ft int
@@ -213,21 +219,33 @@
The
.Fn be_create
function creates a boot environment with the given name.
-It will be created from a snapshot of the currently booted boot environment.
+The new boot environment will be created from a recursive snapshot of the currently
+booted boot environment.
+.Pp
+The
+.Fn be_create_depth
+function creates a boot environment with the given name from an existing snapshot.
+The depth parameter specifies the depth of recursion that will be cloned from the
+existing snapshot. A depth of '0' is no recursion and '-1' is unlimited (i.e. a recursive
+boot environment).
.Pp
The
.Fn be_create_from_existing
function creates a boot environment with the given name from the name of an
-existing boot environment.
-A snapshot will be made of the base boot environment, and the new boot
-environment will be created from that.
+existing boot environment. A recursive snapshot will be made of the origin
+boot environment, and the new boot environment will be created from that.
.Pp
The
.Fn be_create_from_existing_snap
-function creates a boot environment with the given name from an existing
+function creates a recursive boot environment with the given name from an existing
snapshot.
.Pp
The
+.Fn be_create_shallow
+function creates a non-recursive boot environment with the given name from
+an existing snapshot.
+.Pp
+The
.Fn be_rename
function renames a boot environment without unmounting it, as if renamed with
the
Index: lib/libbe/tests/Makefile
===================================================================
--- /dev/null
+++ lib/libbe/tests/Makefile
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+ATF_TESTS_SH+= be_create
+
+PROGS= target_prog
+SRCS_target_prog= target_prog.c
+BINDIR_target_prog= ${TESTSDIR}
+
+LIBADD+= zfs
+LIBADD+= nvpair
+LIBADD+= be
+
+CFLAGS+= -I${SRCTOP}/lib/libbe
+CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris
+CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
+
+CFLAGS+= -DNEED_SOLARIS_BOOLEAN
+
+.include <bsd.test.mk>
Index: lib/libbe/tests/be_create.sh
===================================================================
--- /dev/null
+++ lib/libbe/tests/be_create.sh
@@ -0,0 +1,178 @@
+#
+# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+#
+# Copyright (c) 2019 Rob Wing
+#
+# 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.
+#
+# $FreeBSD$
+
+# The code for the following tests was copied from the
+# bectl tests found in src/sbin/bectl/tests, modified as needed.
+
+ZPOOL_NAME_FILE=zpool_name
+get_zpool_name()
+{
+ cat $ZPOOL_NAME_FILE
+}
+make_zpool_name()
+{
+ mktemp -u libbe_test_XXXXXX > $ZPOOL_NAME_FILE
+ get_zpool_name
+}
+
+# Establishes a libbe zpool that can be used for some light testing; contains
+# a 'default' BE and not much else.
+libbe_create_setup()
+{
+ zpool=$1
+ disk=$2
+ mnt=$3
+
+ # Sanity check to make sure `make_zpool_name` succeeded
+ atf_check test -n "$zpool"
+
+ kldload -n -q zfs || atf_skip "ZFS module not loaded on the current system"
+ atf_check mkdir -p ${mnt}
+ atf_check truncate -s 1G ${disk}
+ atf_check zpool create -o altroot=${mnt} ${zpool} ${disk}
+ atf_check zfs create -o mountpoint=none ${zpool}/ROOT
+ atf_check zfs create -o mountpoint=/ -o canmount=noauto \
+ ${zpool}/ROOT/default
+ atf_check zfs create -o mountpoint=/usr -o canmount=noauto \
+ ${zpool}/ROOT/default/usr
+ atf_check zfs create -o mountpoint=/usr/obj -o canmount=noauto \
+ ${zpool}/ROOT/default/usr/obj
+}
+
+libbe_cleanup()
+{
+ zpool=$1
+ cwd=$(atf_get_srcdir)
+
+ if [ -z "$zpool" ]; then
+ echo "Skipping cleanup; zpool not set up"
+ elif zpool get health ${zpool} >/dev/null 2>&1; then
+ zpool destroy -f ${zpool}
+ fi
+
+ if [ -f "${cwd}/disk.img" ]; then
+ rm ${cwd}/disk.img
+ fi
+}
+
+atf_test_case libbe_create cleanup
+libbe_create_head()
+{
+ atf_set "descr" "check _be_create from libbe"
+ atf_set "require.user" root
+}
+libbe_create_body()
+{
+ cwd=$(atf_get_srcdir)
+ zpool=$(make_zpool_name)
+ disk=${cwd}/disk.img
+ mount=${cwd}/mnt
+ prog=${cwd}/./target_prog
+
+ # preliminary setup/checks
+ atf_require_prog $prog
+ libbe_create_setup ${zpool} ${disk} ${mount}
+
+ # a recursive and non-recursive snapshot to test against
+ atf_check zfs snapshot ${zpool}/ROOT/default@non-recursive
+ atf_check zfs snapshot -r ${zpool}/ROOT/default@recursive
+
+ # create a dataset after snapshots were taken
+ atf_check zfs create -o mountpoint=/usr/src -o canmount=noauto \
+ ${zpool}/ROOT/default/usr/src
+
+ # test boot environment creation with depth of 0 (i.e. a non-recursive boot environment).
+ atf_check $prog "${zpool}/ROOT" \
+ nonrecursive \
+ "${zpool}/ROOT/default@non-recursive" \
+ 0
+ # the dataset should exist
+ atf_check -o not-empty \
+ zfs list "${zpool}/ROOT/nonrecursive"
+ # the child dataset should not exist.
+ atf_check -e not-empty -s not-exit:0 \
+ zfs list "${zpool}/ROOT/nonrecursive/usr"
+
+ # test boot environment creation with unlimited depth (i.e. a recursive boot environment).
+ atf_check $prog "${zpool}/ROOT" \
+ recursive \
+ "${zpool}/ROOT/default@recursive" \
+ -1
+ # the dataset should exist
+ atf_check -o not-empty \
+ zfs list "${zpool}/ROOT/recursive"
+ # the child dataset should exist
+ atf_check -o not-empty \
+ zfs list "${zpool}/ROOT/recursive/usr"
+ # the child dataset should exist
+ atf_check -o not-empty \
+ zfs list "${zpool}/ROOT/recursive/usr/obj"
+ # the child dataset should not exist.
+ atf_check -e not-empty -s not-exit:0 \
+ zfs list "${zpool}/ROOT/recursive/usr/src"
+
+ # test boot environment creation with a depth of 1
+ atf_check $prog "${zpool}/ROOT" \
+ depth \
+ "${zpool}/ROOT/default@recursive" \
+ 1
+ # the child dataset should exist
+ atf_check -o not-empty \
+ zfs list "${zpool}/ROOT/depth/usr"
+ # the child dataset should not exist.
+ atf_check -e not-empty -s not-exit:0 \
+ zfs list "${zpool}/ROOT/depth/usr/obj"
+ # the child dataset should not exist.
+ atf_check -e not-empty -s not-exit:0 \
+ zfs list "${zpool}/ROOT/depth/usr/src"
+
+
+ # create a recursive boot environment named 'relative-snap'.
+ # This test is to ensure that a relative snapshot label can be used,
+ # (i.e. the format: 'bootenvironment@snapshot')
+ atf_check $prog "${zpool}/ROOT" \
+ relative-snap \
+ default@recursive \
+ -1
+ # the dataset should exist
+ atf_check -o not-empty \
+ zfs list "${zpool}/ROOT/relative-snap"
+ # the child dataset should exist
+ atf_check -o not-empty \
+ zfs list "${zpool}/ROOT/relative-snap/usr"
+}
+
+libbe_create_cleanup()
+{
+ libbe_cleanup $(get_zpool_name)
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case libbe_create
+}
Index: lib/libbe/tests/target_prog.c
===================================================================
--- lib/libbe/tests/target_prog.c
+++ lib/libbe/tests/target_prog.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * Copyright (c) 2017 Kyle J. Kneitinger <kyle@kneit.in>
+ * Copyright (c) 2019 Rob Wing
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,53 +24,30 @@
* 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$
*/
-#ifndef _LIBBE_IMPL_H
-#define _LIBBE_IMPL_H
-
-#include <libzfs.h>
-
-#include "be.h"
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
-struct libbe_handle {
- char root[BE_MAXPATHLEN];
- char rootfs[BE_MAXPATHLEN];
- char bootfs[BE_MAXPATHLEN];
- size_t altroot_len;
- zpool_handle_t *active_phandle;
- libzfs_handle_t *lzh;
- be_error_t error;
- bool print_on_err;
-};
+#include <be.h>
-struct libbe_deep_clone {
- libbe_handle_t *lbh;
- const char *bename;
- const char *snapname;
- const char *be_root;
-};
-
-struct libbe_dccb {
- libbe_handle_t *lbh;
- zfs_handle_t *zhp;
- nvlist_t *props;
-};
+/*
+ * argv[1] = root boot environment (e.g. zroot/ROOT),
+ * argv[2] = name of boot environment to create
+ * argv[3] = snapshot to create boot environment from
+ * argv[4] = depth
+ */
+int main(int argc, char *argv[]) {
-typedef struct prop_data {
- nvlist_t *list;
- libbe_handle_t *lbh;
- bool single_object; /* list will contain props directly */
-} prop_data_t;
+ libbe_handle_t *lbh;
-int prop_list_builder_cb(zfs_handle_t *, void *);
-int be_proplist_update(prop_data_t *);
+ if (argc != 5)
+ return -1;
-char *be_mountpoint_augmented(libbe_handle_t *lbh, char *mountpoint);
+ if ((lbh = libbe_init(argv[1])) == NULL)
+ return -1;
-/* Clobbers any previous errors */
-int set_error(libbe_handle_t *, be_error_t);
+ libbe_print_on_error(lbh, true);
-#endif /* _LIBBE_IMPL_H */
+ return (be_create_depth(lbh, argv[2], argv[3], atoi(argv[4])));
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 8, 7:43 PM (12 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28490679
Default Alt Text
D18564.id56370.diff (19 KB)

Event Timeline