Mercurial > illumos > illumos-gate
changeset 3975:6674f5d79069
6282725 hostname/hostid should be stored in the label
author | ek110237 |
---|---|
date | Thu, 05 Apr 2007 13:22:27 -0700 |
parents | a01a9d07ea67 |
children | f77f0b15fc3b |
files | usr/src/cmd/fm/dicts/ZFS.dict usr/src/cmd/fm/dicts/ZFS.po usr/src/cmd/zpool/zpool_main.c usr/src/lib/libzfs/common/libzfs.h usr/src/lib/libzfs/common/libzfs_import.c usr/src/lib/libzfs/common/libzfs_status.c usr/src/lib/libzpool/common/kernel.c usr/src/lib/libzpool/common/sys/zfs_context.h usr/src/uts/common/fs/zfs/spa.c usr/src/uts/common/fs/zfs/spa_config.c usr/src/uts/common/sys/fs/zfs.h |
diffstat | 11 files changed, 176 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/fm/dicts/ZFS.dict Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/cmd/fm/dicts/ZFS.dict Thu Apr 05 13:22:27 2007 -0700 @@ -1,5 +1,5 @@ # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START @@ -40,3 +40,4 @@ ereport.fs.zfs.device.version_mismatch=10 fault.fs.zfs.pool=11 fault.fs.zfs.device=12 +ereport.fs.zfs.pool.hostname_mismatch=13
--- a/usr/src/cmd/fm/dicts/ZFS.po Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/cmd/fm/dicts/ZFS.po Thu Apr 05 13:22:27 2007 -0700 @@ -1,5 +1,5 @@ # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START @@ -217,3 +217,19 @@ msgstr "Fault tolerance of the pool may be compromised." msgid "ZFS-8000-D3.action" msgstr "Run 'zpool status -x' and replace the bad device." +# +# code: ZFS-8000-EY +# keys: ereport.fs.zfs.pool.hostname_mismatch +# +msgid "ZFS-8000-EY.type" +msgstr "Error" +msgid "ZFS-8000-EY.severity" +msgstr "Major" +msgid "ZFS-8000-EY.description" +msgstr "The ZFS pool was last accessed by another system Refer to %s for more information." +msgid "ZFS-8000-EY.response" +msgstr "No automated response will be taken." +msgid "ZFS-8000-EY.impact" +msgstr "ZFS filesystems are not available" +msgid "ZFS-8000-EY.action" +msgstr "\nTo determine which system last accessed the pool, run the 'zpool import'\ncommand:\n\n\n# zpool import\n pool: test\n id: 14702934086626715962\nstate: ONLINE\nstatus: The pool was last accessed by another system.\naction: The pool can be imported using its name or numeric identifier and\n the '-f' flag.\n see: http://www.sun.com/msg/ZFS-XXXXXXX\nconfig:\n\n test ONLINE\n c0t0d0 ONLINE\n\n# zpool import test\ncannot import 'test': pool may be in use from other system, it was last\naccessed by 'tank' (hostid: 0x1435718c) on Fri Mar 9 15:42:47 2007\nuse '-f' to import anyway\n#\n\n\nIf you are certain that the pool is not being actively accessed by another\nsystem, then you can use the '-f' option to 'zpool import' to forcible\nimport the pool.\n "
--- a/usr/src/cmd/zpool/zpool_main.c Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/cmd/zpool/zpool_main.c Thu Apr 05 13:22:27 2007 -0700 @@ -1079,7 +1079,10 @@ (void) printf(gettext("status: The pool is formatted using an " "incompatible version.\n")); break; - + case ZPOOL_STATUS_HOSTID_MISMATCH: + (void) printf(gettext("status: The pool was last accessed by " + "another system.\n")); + break; default: /* * No other status can be seen when importing pools. @@ -1096,6 +1099,10 @@ "imported using its name or numeric identifier, " "though\n\tsome features will not be available " "without an explicit 'zpool upgrade'.\n")); + else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) + (void) printf(gettext("action: The pool can be " + "imported using its name or numeric " + "identifier and\n\tthe '-f' flag.\n")); else (void) printf(gettext("action: The pool can be " "imported using its name or numeric " @@ -1185,10 +1192,37 @@ "is formatted using a newer ZFS version\n"), name); return (1); } else if (state != POOL_STATE_EXPORTED && !force) { - (void) fprintf(stderr, gettext("cannot import '%s': pool " - "may be in use from other system\n"), name); - (void) fprintf(stderr, gettext("use '-f' to import anyway\n")); - return (1); + uint64_t hostid; + + if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, + &hostid) == 0) { + if ((unsigned long)hostid != gethostid()) { + char *hostname; + uint64_t timestamp; + time_t t; + + verify(nvlist_lookup_string(config, + ZPOOL_CONFIG_HOSTNAME, &hostname) == 0); + verify(nvlist_lookup_uint64(config, + ZPOOL_CONFIG_TIMESTAMP, ×tamp) == 0); + t = timestamp; + (void) fprintf(stderr, gettext("cannot import " + "'%s': pool may be in use from other " + "system, it was last accessed by %s " + "(hostid: 0x%lx) on %s"), name, hostname, + (unsigned long)hostid, + asctime(localtime(&t))); + (void) fprintf(stderr, gettext("use '-f' to " + "import anyway\n")); + return (1); + } + } else { + (void) fprintf(stderr, gettext("cannot import '%s': " + "pool may be in use from other system\n"), name); + (void) fprintf(stderr, gettext("use '-f' to import " + "anyway\n")); + return (1); + } } if (zpool_import(g_zfs, config, newname, altroot) != 0)
--- a/usr/src/lib/libzfs/common/libzfs.h Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/lib/libzfs/common/libzfs.h Thu Apr 05 13:22:27 2007 -0700 @@ -191,6 +191,7 @@ ZPOOL_STATUS_CORRUPT_DATA, /* data errors in user (meta)data */ ZPOOL_STATUS_FAILING_DEV, /* device experiencing errors */ ZPOOL_STATUS_VERSION_NEWER, /* newer on-disk version */ + ZPOOL_STATUS_HOSTID_MISMATCH, /* last accessed by another system */ /* * The following are not faults per se, but still an error possibly
--- a/usr/src/lib/libzfs/common/libzfs_import.c Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/lib/libzfs/common/libzfs_import.c Thu Apr 05 13:22:27 2007 -0700 @@ -379,7 +379,7 @@ uint_t i, nspares; boolean_t config_seen; uint64_t best_txg; - char *name; + char *name, *hostname; zfs_cmd_t zc = { 0 }; uint64_t version, guid; size_t len; @@ -388,6 +388,7 @@ nvlist_t **child = NULL; uint_t c; boolean_t isactive; + uint64_t hostid; if (nvlist_alloc(&ret, 0, 0) != 0) goto nomem; @@ -430,6 +431,8 @@ * pool guid * name * pool state + * hostid (if available) + * hostname (if available) */ uint64_t state; @@ -453,6 +456,20 @@ if (nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE, state) != 0) goto nomem; + hostid = 0; + if (nvlist_lookup_uint64(tmp, + ZPOOL_CONFIG_HOSTID, &hostid) == 0) { + if (nvlist_add_uint64(config, + ZPOOL_CONFIG_HOSTID, hostid) != 0) + goto nomem; + verify(nvlist_lookup_string(tmp, + ZPOOL_CONFIG_HOSTNAME, + &hostname) == 0); + if (nvlist_add_string(config, + ZPOOL_CONFIG_HOSTNAME, + hostname) != 0) + goto nomem; + } config_seen = B_TRUE; } @@ -622,6 +639,20 @@ } /* + * Restore the original information read from the actual label. + */ + (void) nvlist_remove(config, ZPOOL_CONFIG_HOSTID, + DATA_TYPE_UINT64); + (void) nvlist_remove(config, ZPOOL_CONFIG_HOSTNAME, + DATA_TYPE_STRING); + if (hostid != 0) { + verify(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID, + hostid) == 0); + verify(nvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME, + hostname) == 0); + } + + /* * Add this pool to the list of configs. */ verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
--- a/usr/src/lib/libzfs/common/libzfs_status.c Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/lib/libzfs/common/libzfs_status.c Thu Apr 05 13:22:27 2007 -0700 @@ -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. */ @@ -43,6 +43,7 @@ #include <libzfs.h> #include <string.h> +#include <unistd.h> #include "libzfs_impl.h" /* @@ -50,7 +51,7 @@ * in libzfs.h. Note that there are some status results which go past the end * of this table, and hence have no associated message ID. */ -static char *msgid_table[] = { +static char *zfs_msgid_table[] = { "ZFS-8000-14", "ZFS-8000-2Q", "ZFS-8000-3C", @@ -60,7 +61,8 @@ "ZFS-8000-72", "ZFS-8000-8A", "ZFS-8000-9P", - "ZFS-8000-A5" + "ZFS-8000-A5", + "ZFS-8000-EY" }; /* @@ -69,7 +71,7 @@ * and the article referred to by 'zpool status' must match that indicated by * the syslog error message. We override missing data as well as corrupt pool. */ -static char *msgid_table_active[] = { +static char *zfs_msgid_table_active[] = { "ZFS-8000-14", "ZFS-8000-D3", /* overridden */ "ZFS-8000-D3", /* overridden */ @@ -82,7 +84,7 @@ "ZFS-8000-CS", /* overridden */ }; -#define NMSGID (sizeof (msgid_table) / sizeof (msgid_table[0])) +#define NMSGID (sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0])) /* ARGSUSED */ static int @@ -178,6 +180,8 @@ uint_t vsc; uint64_t nerr; uint64_t version; + uint64_t stateval; + uint64_t hostid = 0; verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) == 0); @@ -185,6 +189,16 @@ &nvroot) == 0); verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, (uint64_t **)&vs, &vsc) == 0); + verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, + &stateval) == 0); + (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid); + + /* + * Pool last accessed by another system. + */ + if (hostid != 0 && (unsigned long)hostid != gethostid() && + stateval == POOL_STATE_ACTIVE) + return (ZPOOL_STATUS_HOSTID_MISMATCH); /* * Newer on-disk version. @@ -270,7 +284,7 @@ if (ret >= NMSGID) *msgid = NULL; else - *msgid = msgid_table_active[ret]; + *msgid = zfs_msgid_table_active[ret]; return (ret); } @@ -283,7 +297,7 @@ if (ret >= NMSGID) *msgid = NULL; else - *msgid = msgid_table[ret]; + *msgid = zfs_msgid_table[ret]; return (ret); }
--- a/usr/src/lib/libzpool/common/kernel.c Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/lib/libzpool/common/kernel.c Thu Apr 05 13:22:27 2007 -0700 @@ -37,6 +37,7 @@ #include <sys/processor.h> #include <sys/zfs_context.h> #include <sys/zmod.h> +#include <sys/utsname.h> /* * Emulation of kernel services in userland. @@ -44,6 +45,11 @@ uint64_t physmem; vnode_t *rootdir = (vnode_t *)0xabcd1234; +char hw_serial[11]; + +struct utsname utsname = { + "userland", "libzpool", "1", "1", "na" +}; /* * ========================================================================= @@ -723,6 +729,17 @@ return (random_get_bytes_common(ptr, len, "/dev/urandom")); } +int +ddi_strtoul(const char *hw_serial, char **nptr, int base, unsigned long *result) +{ + char *end; + + *result = strtoul(hw_serial, &end, base); + if (*result == 0) + return (errno); + return (0); +} + /* * ========================================================================= * kernel emulation setup & teardown @@ -748,6 +765,8 @@ dprintf("physmem = %llu pages (%.2f GB)\n", physmem, (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30)); + snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid()); + spa_init(mode); }
--- a/usr/src/lib/libzpool/common/sys/zfs_context.h Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/lib/libzpool/common/sys/zfs_context.h Thu Apr 05 13:22:27 2007 -0700 @@ -425,6 +425,13 @@ #define zone_dataset_visible(x, y) (1) #define INGLOBALZONE(z) (1) +/* + * Hostname information + */ +extern char hw_serial[]; +extern int ddi_strtoul(const char *str, char **nptr, int base, + unsigned long *result); + #ifdef __cplusplus } #endif
--- a/usr/src/uts/common/fs/zfs/spa.c Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/uts/common/fs/zfs/spa.c Thu Apr 05 13:22:27 2007 -0700 @@ -57,6 +57,8 @@ #include <sys/dsl_synctask.h> #include <sys/fs/zfs.h> #include <sys/callb.h> +#include <sys/systeminfo.h> +#include <sys/sunddi.h> int zio_taskq_threads = 8; @@ -572,6 +574,7 @@ 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, @@ -580,6 +583,27 @@ 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); @@ -1359,6 +1383,8 @@ 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.
--- a/usr/src/uts/common/fs/zfs/spa_config.c Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/uts/common/fs/zfs/spa_config.c Thu Apr 05 13:22:27 2007 -0700 @@ -33,6 +33,9 @@ #include <sys/fs/zfs.h> #include <sys/vdev_impl.h> #include <sys/zfs_ioctl.h> +#include <sys/utsname.h> +#include <sys/systeminfo.h> +#include <sys/sunddi.h> #ifdef _KERNEL #include <sys/kobj.h> #endif @@ -265,6 +268,7 @@ { nvlist_t *config, *nvroot; vdev_t *rvd = spa->spa_root_vdev; + unsigned long hostid = 0; ASSERT(spa_config_held(spa, RW_READER)); @@ -289,6 +293,11 @@ 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,
--- a/usr/src/uts/common/sys/fs/zfs.h Thu Apr 05 11:27:36 2007 -0700 +++ b/usr/src/uts/common/sys/fs/zfs.h Thu Apr 05 13:22:27 2007 -0700 @@ -207,6 +207,9 @@ #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"