summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/cddl/compat/opensolaris/kern/opensolaris_misc.c55
-rw-r--r--sys/cddl/compat/opensolaris/sys/misc.h40
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c21
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c33
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c25
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c24
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c7
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h3
-rw-r--r--sys/compat/opensolaris/kern/opensolaris_misc.c55
-rw-r--r--sys/compat/opensolaris/sys/misc.h40
-rw-r--r--sys/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c21
-rw-r--r--sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c33
-rw-r--r--sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c25
-rw-r--r--sys/contrib/opensolaris/uts/common/fs/zfs/spa.c24
-rw-r--r--sys/contrib/opensolaris/uts/common/fs/zfs/spa_config.c7
-rw-r--r--sys/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h3
-rw-r--r--sys/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h2
-rw-r--r--sys/contrib/opensolaris/uts/common/sys/fs/zfs.h3
-rw-r--r--sys/modules/zfs/Makefile1
21 files changed, 403 insertions, 24 deletions
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_misc.c b/sys/cddl/compat/opensolaris/kern/opensolaris_misc.c
new file mode 100644
index 0000000..bb51c37
--- /dev/null
+++ b/sys/cddl/compat/opensolaris/kern/opensolaris_misc.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * 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 AUTHORS 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 AUTHORS 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>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include <sys/misc.h>
+
+char hw_serial[11] = "0";
+
+struct opensolaris_utsname utsname = {
+ .nodename = hostname
+};
+
+int
+ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result)
+{
+ char *end;
+
+ if (str == hw_serial) {
+ *result = hostid;
+ return (0);
+ }
+
+ *result = strtoul(str, &end, base);
+ if (*result == 0)
+ return (EINVAL);
+ return (0);
+}
diff --git a/sys/cddl/compat/opensolaris/sys/misc.h b/sys/cddl/compat/opensolaris/sys/misc.h
new file mode 100644
index 0000000..d18c8c7
--- /dev/null
+++ b/sys/cddl/compat/opensolaris/sys/misc.h
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * 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 AUTHORS 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 AUTHORS 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$
+ */
+
+#ifndef _OPENSOLARIS_SYS_MISC_H_
+#define _OPENSOLARIS_SYS_MISC_H_
+
+struct opensolaris_utsname {
+ char *nodename;
+};
+
+extern char hw_serial[11];
+extern struct opensolaris_utsname utsname;
+
+int ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result);
+#endif /* _OPENSOLARIS_SYS_MISC_H_ */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
index 07f8c86..378fe8c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
@@ -948,7 +948,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
objset_t *os;
uint64_t snapobj;
zap_cursor_t zc;
- zap_attribute_t attr;
+ zap_attribute_t *attr;
char *child;
int do_self, err;
@@ -958,6 +958,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
/* NB: the $MOS dir doesn't have a head dataset */
do_self = (dd->dd_phys->dd_head_dataset_obj != 0);
+ attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
/*
* Iterate over all children.
@@ -965,10 +966,10 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
if (flags & DS_FIND_CHILDREN) {
for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset,
dd->dd_phys->dd_child_dir_zapobj);
- zap_cursor_retrieve(&zc, &attr) == 0;
+ zap_cursor_retrieve(&zc, attr) == 0;
(void) zap_cursor_advance(&zc)) {
- ASSERT(attr.za_integer_length == sizeof (uint64_t));
- ASSERT(attr.za_num_integers == 1);
+ ASSERT(attr->za_integer_length == sizeof (uint64_t));
+ ASSERT(attr->za_num_integers == 1);
/*
* No separating '/' because parent's name ends in /.
@@ -977,7 +978,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
/* XXX could probably just use name here */
dsl_dir_name(dd, child);
(void) strcat(child, "/");
- (void) strcat(child, attr.za_name);
+ (void) strcat(child, attr->za_name);
err = dmu_objset_find(child, func, arg, flags);
kmem_free(child, MAXPATHLEN);
if (err)
@@ -987,6 +988,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
if (err) {
dsl_dir_close(dd, FTAG);
+ kmem_free(attr, sizeof (zap_attribute_t));
return (err);
}
}
@@ -1002,16 +1004,16 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
dmu_objset_close(os);
for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, snapobj);
- zap_cursor_retrieve(&zc, &attr) == 0;
+ zap_cursor_retrieve(&zc, attr) == 0;
(void) zap_cursor_advance(&zc)) {
- ASSERT(attr.za_integer_length == sizeof (uint64_t));
- ASSERT(attr.za_num_integers == 1);
+ ASSERT(attr->za_integer_length == sizeof (uint64_t));
+ ASSERT(attr->za_num_integers == 1);
child = kmem_alloc(MAXPATHLEN, KM_SLEEP);
/* XXX could probably just use name here */
dsl_dir_name(dd, child);
(void) strcat(child, "@");
- (void) strcat(child, attr.za_name);
+ (void) strcat(child, attr->za_name);
err = func(child, arg);
kmem_free(child, MAXPATHLEN);
if (err)
@@ -1021,6 +1023,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
}
dsl_dir_close(dd, FTAG);
+ kmem_free(attr, sizeof (zap_attribute_t));
if (err)
return (err);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
index a9707a0..af06c31 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
@@ -491,6 +491,32 @@ dsl_dataset_name(dsl_dataset_t *ds, char *name)
}
}
+static int
+dsl_dataset_namelen(dsl_dataset_t *ds)
+{
+ int result;
+
+ if (ds == NULL) {
+ result = 3; /* "mos" */
+ } else {
+ result = dsl_dir_namelen(ds->ds_dir);
+ VERIFY(0 == dsl_dataset_get_snapname(ds));
+ if (ds->ds_snapname[0]) {
+ ++result; /* adding one for the @-sign */
+ if (!MUTEX_HELD(&ds->ds_lock)) {
+ /* see dsl_datset_name */
+ mutex_enter(&ds->ds_lock);
+ result += strlen(ds->ds_snapname);
+ mutex_exit(&ds->ds_lock);
+ } else {
+ result += strlen(ds->ds_snapname);
+ }
+ }
+ }
+
+ return (result);
+}
+
void
dsl_dataset_close(dsl_dataset_t *ds, int mode, void *tag)
{
@@ -1328,6 +1354,13 @@ dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx)
if (err != ENOENT)
return (err);
+ /*
+ * Check that the dataset's name is not too long. Name consists
+ * of the dataset's length + 1 for the @-sign + snapshot name's length
+ */
+ if (dsl_dataset_namelen(ds) + 1 + strlen(snapname) >= MAXNAMELEN)
+ return (ENAMETOOLONG);
+
ds->ds_trysnap_txg = tx->tx_txg;
return (0);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
index 97779a2..5e563b6 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -207,6 +207,29 @@ dsl_dir_name(dsl_dir_t *dd, char *buf)
}
}
+/* Calculate name legnth, avoiding all the strcat calls of dsl_dir_name */
+int
+dsl_dir_namelen(dsl_dir_t *dd)
+{
+ int result = 0;
+
+ if (dd->dd_parent) {
+ /* parent's name + 1 for the "/" */
+ result = dsl_dir_namelen(dd->dd_parent) + 1;
+ }
+
+ if (!MUTEX_HELD(&dd->dd_lock)) {
+ /* see dsl_dir_name */
+ mutex_enter(&dd->dd_lock);
+ result += strlen(dd->dd_myname);
+ mutex_exit(&dd->dd_lock);
+ } else {
+ result += strlen(dd->dd_myname);
+ }
+
+ return (result);
+}
+
int
dsl_dir_is_private(dsl_dir_t *dd)
{
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
index c218f72..bfaa5e7 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
@@ -579,6 +579,7 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig)
if (!mosconfig) {
nvlist_t *newconfig;
+ uint64_t hostid;
if (load_nvlist(spa, spa->spa_config_object, &newconfig) != 0) {
vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
@@ -587,6 +588,27 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig)
goto out;
}
+ if (nvlist_lookup_uint64(newconfig, ZPOOL_CONFIG_HOSTID,
+ &hostid) == 0) {
+ char *hostname;
+ unsigned long myhostid = 0;
+
+ VERIFY(nvlist_lookup_string(newconfig,
+ ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
+
+ (void) ddi_strtoul(hw_serial, NULL, 10, &myhostid);
+ if ((unsigned long)hostid != myhostid) {
+ cmn_err(CE_WARN, "pool '%s' could not be "
+ "loaded as it was last accessed by "
+ "another system (host: %s hostid: 0x%lx). "
+ "See: http://www.sun.com/msg/ZFS-8000-EY",
+ spa->spa_name, hostname,
+ (unsigned long)hostid);
+ error = EBADF;
+ goto out;
+ }
+ }
+
spa_config_set(spa, newconfig);
spa_unload(spa);
spa_deactivate(spa);
@@ -1366,6 +1388,8 @@ spa_tryimport(nvlist_t *tryconfig)
poolname) == 0);
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE,
state) == 0);
+ VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TIMESTAMP,
+ spa->spa_uberblock.ub_timestamp) == 0);
/*
* Add the list of hot spares.
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
index b5d8c38..a7498ff 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
@@ -34,6 +34,7 @@
#include <sys/fs/zfs.h>
#include <sys/vdev_impl.h>
#include <sys/zfs_ioctl.h>
+#include <sys/utsname.h>
#ifdef _KERNEL
#include <sys/kobj.h>
#endif
@@ -268,6 +269,7 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
{
nvlist_t *config, *nvroot;
vdev_t *rvd = spa->spa_root_vdev;
+ unsigned long hostid = 0;
ASSERT(spa_config_held(spa, RW_READER));
@@ -292,6 +294,11 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
txg) == 0);
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
spa_guid(spa)) == 0);
+ (void) ddi_strtoul(hw_serial, NULL, 10, &hostid);
+ VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID,
+ hostid) == 0);
+ VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME,
+ utsname.nodename) == 0);
if (vd != rvd) {
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID,
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h
index f33776a..e0595d3 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -97,6 +97,7 @@ int dsl_dir_open_spa(spa_t *spa, const char *name, void *tag, dsl_dir_t **,
int dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj,
const char *tail, void *tag, dsl_dir_t **);
void dsl_dir_name(dsl_dir_t *dd, char *buf);
+int dsl_dir_namelen(dsl_dir_t *dd);
int dsl_dir_is_private(dsl_dir_t *dd);
uint64_t dsl_dir_create_sync(dsl_dir_t *pds, const char *name, dmu_tx_t *tx);
void dsl_dir_create_root(objset_t *mos, uint64_t *ddobjp, dmu_tx_t *tx);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h
index c91d807..454126f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h
@@ -46,7 +46,6 @@ extern "C" {
#include <sys/kmem.h>
#include <sys/taskq.h>
#include <sys/systm.h>
-#include <sys/kobj.h>
#include <sys/conf.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
@@ -77,6 +76,7 @@ extern "C" {
#include <sys/policy.h>
#include <sys/zone.h>
#include <sys/eventhandler.h>
+#include <sys/misc.h>
#include <sys/zfs_debug.h>
#include <machine/stdarg.h>
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
index 715537d..4416a5a 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
@@ -208,6 +208,9 @@ extern zpool_prop_t zpool_prop_iter(zpool_prop_f, void *, boolean_t);
#define ZPOOL_CONFIG_SPARES "spares"
#define ZPOOL_CONFIG_IS_SPARE "is_spare"
#define ZPOOL_CONFIG_NPARITY "nparity"
+#define ZPOOL_CONFIG_HOSTID "hostid"
+#define ZPOOL_CONFIG_HOSTNAME "hostname"
+#define ZPOOL_CONFIG_TIMESTAMP "timestamp" /* not stored on disk */
#define VDEV_TYPE_ROOT "root"
#define VDEV_TYPE_MIRROR "mirror"
diff --git a/sys/compat/opensolaris/kern/opensolaris_misc.c b/sys/compat/opensolaris/kern/opensolaris_misc.c
new file mode 100644
index 0000000..bb51c37
--- /dev/null
+++ b/sys/compat/opensolaris/kern/opensolaris_misc.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * 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 AUTHORS 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 AUTHORS 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>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include <sys/misc.h>
+
+char hw_serial[11] = "0";
+
+struct opensolaris_utsname utsname = {
+ .nodename = hostname
+};
+
+int
+ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result)
+{
+ char *end;
+
+ if (str == hw_serial) {
+ *result = hostid;
+ return (0);
+ }
+
+ *result = strtoul(str, &end, base);
+ if (*result == 0)
+ return (EINVAL);
+ return (0);
+}
diff --git a/sys/compat/opensolaris/sys/misc.h b/sys/compat/opensolaris/sys/misc.h
new file mode 100644
index 0000000..d18c8c7
--- /dev/null
+++ b/sys/compat/opensolaris/sys/misc.h
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * 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 AUTHORS 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 AUTHORS 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$
+ */
+
+#ifndef _OPENSOLARIS_SYS_MISC_H_
+#define _OPENSOLARIS_SYS_MISC_H_
+
+struct opensolaris_utsname {
+ char *nodename;
+};
+
+extern char hw_serial[11];
+extern struct opensolaris_utsname utsname;
+
+int ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result);
+#endif /* _OPENSOLARIS_SYS_MISC_H_ */
diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
index 07f8c86..378fe8c 100644
--- a/sys/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
+++ b/sys/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
@@ -948,7 +948,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
objset_t *os;
uint64_t snapobj;
zap_cursor_t zc;
- zap_attribute_t attr;
+ zap_attribute_t *attr;
char *child;
int do_self, err;
@@ -958,6 +958,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
/* NB: the $MOS dir doesn't have a head dataset */
do_self = (dd->dd_phys->dd_head_dataset_obj != 0);
+ attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
/*
* Iterate over all children.
@@ -965,10 +966,10 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
if (flags & DS_FIND_CHILDREN) {
for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset,
dd->dd_phys->dd_child_dir_zapobj);
- zap_cursor_retrieve(&zc, &attr) == 0;
+ zap_cursor_retrieve(&zc, attr) == 0;
(void) zap_cursor_advance(&zc)) {
- ASSERT(attr.za_integer_length == sizeof (uint64_t));
- ASSERT(attr.za_num_integers == 1);
+ ASSERT(attr->za_integer_length == sizeof (uint64_t));
+ ASSERT(attr->za_num_integers == 1);
/*
* No separating '/' because parent's name ends in /.
@@ -977,7 +978,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
/* XXX could probably just use name here */
dsl_dir_name(dd, child);
(void) strcat(child, "/");
- (void) strcat(child, attr.za_name);
+ (void) strcat(child, attr->za_name);
err = dmu_objset_find(child, func, arg, flags);
kmem_free(child, MAXPATHLEN);
if (err)
@@ -987,6 +988,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
if (err) {
dsl_dir_close(dd, FTAG);
+ kmem_free(attr, sizeof (zap_attribute_t));
return (err);
}
}
@@ -1002,16 +1004,16 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
dmu_objset_close(os);
for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, snapobj);
- zap_cursor_retrieve(&zc, &attr) == 0;
+ zap_cursor_retrieve(&zc, attr) == 0;
(void) zap_cursor_advance(&zc)) {
- ASSERT(attr.za_integer_length == sizeof (uint64_t));
- ASSERT(attr.za_num_integers == 1);
+ ASSERT(attr->za_integer_length == sizeof (uint64_t));
+ ASSERT(attr->za_num_integers == 1);
child = kmem_alloc(MAXPATHLEN, KM_SLEEP);
/* XXX could probably just use name here */
dsl_dir_name(dd, child);
(void) strcat(child, "@");
- (void) strcat(child, attr.za_name);
+ (void) strcat(child, attr->za_name);
err = func(child, arg);
kmem_free(child, MAXPATHLEN);
if (err)
@@ -1021,6 +1023,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
}
dsl_dir_close(dd, FTAG);
+ kmem_free(attr, sizeof (zap_attribute_t));
if (err)
return (err);
diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
index a9707a0..af06c31 100644
--- a/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
+++ b/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
@@ -491,6 +491,32 @@ dsl_dataset_name(dsl_dataset_t *ds, char *name)
}
}
+static int
+dsl_dataset_namelen(dsl_dataset_t *ds)
+{
+ int result;
+
+ if (ds == NULL) {
+ result = 3; /* "mos" */
+ } else {
+ result = dsl_dir_namelen(ds->ds_dir);
+ VERIFY(0 == dsl_dataset_get_snapname(ds));
+ if (ds->ds_snapname[0]) {
+ ++result; /* adding one for the @-sign */
+ if (!MUTEX_HELD(&ds->ds_lock)) {
+ /* see dsl_datset_name */
+ mutex_enter(&ds->ds_lock);
+ result += strlen(ds->ds_snapname);
+ mutex_exit(&ds->ds_lock);
+ } else {
+ result += strlen(ds->ds_snapname);
+ }
+ }
+ }
+
+ return (result);
+}
+
void
dsl_dataset_close(dsl_dataset_t *ds, int mode, void *tag)
{
@@ -1328,6 +1354,13 @@ dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx)
if (err != ENOENT)
return (err);
+ /*
+ * Check that the dataset's name is not too long. Name consists
+ * of the dataset's length + 1 for the @-sign + snapshot name's length
+ */
+ if (dsl_dataset_namelen(ds) + 1 + strlen(snapname) >= MAXNAMELEN)
+ return (ENAMETOOLONG);
+
ds->ds_trysnap_txg = tx->tx_txg;
return (0);
}
diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c b/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
index 97779a2..5e563b6 100644
--- a/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
+++ b/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -207,6 +207,29 @@ dsl_dir_name(dsl_dir_t *dd, char *buf)
}
}
+/* Calculate name legnth, avoiding all the strcat calls of dsl_dir_name */
+int
+dsl_dir_namelen(dsl_dir_t *dd)
+{
+ int result = 0;
+
+ if (dd->dd_parent) {
+ /* parent's name + 1 for the "/" */
+ result = dsl_dir_namelen(dd->dd_parent) + 1;
+ }
+
+ if (!MUTEX_HELD(&dd->dd_lock)) {
+ /* see dsl_dir_name */
+ mutex_enter(&dd->dd_lock);
+ result += strlen(dd->dd_myname);
+ mutex_exit(&dd->dd_lock);
+ } else {
+ result += strlen(dd->dd_myname);
+ }
+
+ return (result);
+}
+
int
dsl_dir_is_private(dsl_dir_t *dd)
{
diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c
index c218f72..bfaa5e7 100644
--- a/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c
+++ b/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c
@@ -579,6 +579,7 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig)
if (!mosconfig) {
nvlist_t *newconfig;
+ uint64_t hostid;
if (load_nvlist(spa, spa->spa_config_object, &newconfig) != 0) {
vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
@@ -587,6 +588,27 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig)
goto out;
}
+ if (nvlist_lookup_uint64(newconfig, ZPOOL_CONFIG_HOSTID,
+ &hostid) == 0) {
+ char *hostname;
+ unsigned long myhostid = 0;
+
+ VERIFY(nvlist_lookup_string(newconfig,
+ ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
+
+ (void) ddi_strtoul(hw_serial, NULL, 10, &myhostid);
+ if ((unsigned long)hostid != myhostid) {
+ cmn_err(CE_WARN, "pool '%s' could not be "
+ "loaded as it was last accessed by "
+ "another system (host: %s hostid: 0x%lx). "
+ "See: http://www.sun.com/msg/ZFS-8000-EY",
+ spa->spa_name, hostname,
+ (unsigned long)hostid);
+ error = EBADF;
+ goto out;
+ }
+ }
+
spa_config_set(spa, newconfig);
spa_unload(spa);
spa_deactivate(spa);
@@ -1366,6 +1388,8 @@ spa_tryimport(nvlist_t *tryconfig)
poolname) == 0);
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE,
state) == 0);
+ VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TIMESTAMP,
+ spa->spa_uberblock.ub_timestamp) == 0);
/*
* Add the list of hot spares.
diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/spa_config.c b/sys/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
index b5d8c38..a7498ff 100644
--- a/sys/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
+++ b/sys/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
@@ -34,6 +34,7 @@
#include <sys/fs/zfs.h>
#include <sys/vdev_impl.h>
#include <sys/zfs_ioctl.h>
+#include <sys/utsname.h>
#ifdef _KERNEL
#include <sys/kobj.h>
#endif
@@ -268,6 +269,7 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
{
nvlist_t *config, *nvroot;
vdev_t *rvd = spa->spa_root_vdev;
+ unsigned long hostid = 0;
ASSERT(spa_config_held(spa, RW_READER));
@@ -292,6 +294,11 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
txg) == 0);
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
spa_guid(spa)) == 0);
+ (void) ddi_strtoul(hw_serial, NULL, 10, &hostid);
+ VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID,
+ hostid) == 0);
+ VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME,
+ utsname.nodename) == 0);
if (vd != rvd) {
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID,
diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h b/sys/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h
index f33776a..e0595d3 100644
--- a/sys/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h
+++ b/sys/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -97,6 +97,7 @@ int dsl_dir_open_spa(spa_t *spa, const char *name, void *tag, dsl_dir_t **,
int dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj,
const char *tail, void *tag, dsl_dir_t **);
void dsl_dir_name(dsl_dir_t *dd, char *buf);
+int dsl_dir_namelen(dsl_dir_t *dd);
int dsl_dir_is_private(dsl_dir_t *dd);
uint64_t dsl_dir_create_sync(dsl_dir_t *pds, const char *name, dmu_tx_t *tx);
void dsl_dir_create_root(objset_t *mos, uint64_t *ddobjp, dmu_tx_t *tx);
diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h b/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h
index c91d807..454126f 100644
--- a/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h
+++ b/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h
@@ -46,7 +46,6 @@ extern "C" {
#include <sys/kmem.h>
#include <sys/taskq.h>
#include <sys/systm.h>
-#include <sys/kobj.h>
#include <sys/conf.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
@@ -77,6 +76,7 @@ extern "C" {
#include <sys/policy.h>
#include <sys/zone.h>
#include <sys/eventhandler.h>
+#include <sys/misc.h>
#include <sys/zfs_debug.h>
#include <machine/stdarg.h>
diff --git a/sys/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/contrib/opensolaris/uts/common/sys/fs/zfs.h
index 715537d..4416a5a 100644
--- a/sys/contrib/opensolaris/uts/common/sys/fs/zfs.h
+++ b/sys/contrib/opensolaris/uts/common/sys/fs/zfs.h
@@ -208,6 +208,9 @@ extern zpool_prop_t zpool_prop_iter(zpool_prop_f, void *, boolean_t);
#define ZPOOL_CONFIG_SPARES "spares"
#define ZPOOL_CONFIG_IS_SPARE "is_spare"
#define ZPOOL_CONFIG_NPARITY "nparity"
+#define ZPOOL_CONFIG_HOSTID "hostid"
+#define ZPOOL_CONFIG_HOSTNAME "hostname"
+#define ZPOOL_CONFIG_TIMESTAMP "timestamp" /* not stored on disk */
#define VDEV_TYPE_ROOT "root"
#define VDEV_TYPE_MIRROR "mirror"
diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile
index 1f3fbbf..80f43a5 100644
--- a/sys/modules/zfs/Makefile
+++ b/sys/modules/zfs/Makefile
@@ -15,6 +15,7 @@ SRCS+= nvpair.c
SRCS+= opensolaris_kmem.c
SRCS+= opensolaris_kobj.c
SRCS+= opensolaris_kstat.c
+SRCS+= opensolaris_misc.c
SRCS+= opensolaris_policy.c
SRCS+= opensolaris_string.c
SRCS+= opensolaris_vfs.c
OpenPOWER on IntegriCloud