MFp4: Synchronize with recent OpenSolaris changes.
This commit is contained in:
parent
86e97941c4
commit
ffe54ff0ec
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=168498
@ -1082,6 +1082,10 @@ show_import(nvlist_t *config)
|
|||||||
"incompatible version.\n"));
|
"incompatible version.\n"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ZPOOL_STATUS_HOSTID_MISMATCH:
|
||||||
|
(void) printf(gettext("status: The pool was last accessed by "
|
||||||
|
"another system.\n"));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* No other status can be seen when importing pools.
|
* No other status can be seen when importing pools.
|
||||||
@ -1098,6 +1102,10 @@ show_import(nvlist_t *config)
|
|||||||
"imported using its name or numeric identifier, "
|
"imported using its name or numeric identifier, "
|
||||||
"though\n\tsome features will not be available "
|
"though\n\tsome features will not be available "
|
||||||
"without an explicit 'zpool upgrade'.\n"));
|
"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
|
else
|
||||||
(void) printf(gettext("action: The pool can be "
|
(void) printf(gettext("action: The pool can be "
|
||||||
"imported using its name or numeric "
|
"imported using its name or numeric "
|
||||||
@ -1187,10 +1195,37 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
|||||||
"is formatted using a newer ZFS version\n"), name);
|
"is formatted using a newer ZFS version\n"), name);
|
||||||
return (1);
|
return (1);
|
||||||
} else if (state != POOL_STATE_EXPORTED && !force) {
|
} else if (state != POOL_STATE_EXPORTED && !force) {
|
||||||
(void) fprintf(stderr, gettext("cannot import '%s': pool "
|
uint64_t hostid;
|
||||||
"may be in use from other system\n"), name);
|
|
||||||
(void) fprintf(stderr, gettext("use '-f' to import anyway\n"));
|
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
|
||||||
return (1);
|
&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)
|
if (zpool_import(g_zfs, config, newname, altroot) != 0)
|
||||||
|
@ -246,6 +246,8 @@ extern uint16_t zio_zil_fail_shift;
|
|||||||
#define ZTEST_DIROBJ_BLOCKSIZE (1 << 10)
|
#define ZTEST_DIROBJ_BLOCKSIZE (1 << 10)
|
||||||
#define ZTEST_DIRSIZE 256
|
#define ZTEST_DIRSIZE 256
|
||||||
|
|
||||||
|
static void usage(boolean_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These libumem hooks provide a reasonable set of defaults for the allocator's
|
* These libumem hooks provide a reasonable set of defaults for the allocator's
|
||||||
* debugging facilities.
|
* debugging facilities.
|
||||||
@ -303,13 +305,17 @@ str2shift(const char *buf)
|
|||||||
if (toupper(buf[0]) == ends[i])
|
if (toupper(buf[0]) == ends[i])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == strlen(ends))
|
if (i == strlen(ends)) {
|
||||||
fatal(0, "invalid bytes suffix: %s", buf);
|
(void) fprintf(stderr, "ztest: invalid bytes suffix: %s\n",
|
||||||
|
buf);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0')) {
|
if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0')) {
|
||||||
return (10*i);
|
return (10*i);
|
||||||
}
|
}
|
||||||
fatal(0, "invalid bytes suffix: %s", buf);
|
(void) fprintf(stderr, "ztest: invalid bytes suffix: %s\n", buf);
|
||||||
return (-1);
|
usage(B_FALSE);
|
||||||
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
@ -320,32 +326,40 @@ nicenumtoull(const char *buf)
|
|||||||
|
|
||||||
val = strtoull(buf, &end, 0);
|
val = strtoull(buf, &end, 0);
|
||||||
if (end == buf) {
|
if (end == buf) {
|
||||||
fatal(0, "bad numeric value: %s", buf);
|
(void) fprintf(stderr, "ztest: bad numeric value: %s\n", buf);
|
||||||
|
usage(B_FALSE);
|
||||||
} else if (end[0] == '.') {
|
} else if (end[0] == '.') {
|
||||||
double fval = strtod(buf, &end);
|
double fval = strtod(buf, &end);
|
||||||
fval *= pow(2, str2shift(end));
|
fval *= pow(2, str2shift(end));
|
||||||
if (fval > UINT64_MAX)
|
if (fval > UINT64_MAX) {
|
||||||
fatal(0, "value too large: %s", buf);
|
(void) fprintf(stderr, "ztest: value too large: %s\n",
|
||||||
|
buf);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
val = (uint64_t)fval;
|
val = (uint64_t)fval;
|
||||||
} else {
|
} else {
|
||||||
int shift = str2shift(end);
|
int shift = str2shift(end);
|
||||||
if (shift >= 64 || (val << shift) >> shift != val)
|
if (shift >= 64 || (val << shift) >> shift != val) {
|
||||||
fatal(0, "value too large: %s", buf);
|
(void) fprintf(stderr, "ztest: value too large: %s\n",
|
||||||
|
buf);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
val <<= shift;
|
val <<= shift;
|
||||||
}
|
}
|
||||||
return (val);
|
return (val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(boolean_t requested)
|
||||||
{
|
{
|
||||||
char nice_vdev_size[10];
|
char nice_vdev_size[10];
|
||||||
char nice_gang_bang[10];
|
char nice_gang_bang[10];
|
||||||
|
FILE *fp = requested ? stdout : stderr;
|
||||||
|
|
||||||
nicenum(zopt_vdev_size, nice_vdev_size);
|
nicenum(zopt_vdev_size, nice_vdev_size);
|
||||||
nicenum(zio_gang_bang, nice_gang_bang);
|
nicenum(zio_gang_bang, nice_gang_bang);
|
||||||
|
|
||||||
(void) printf("Usage: %s\n"
|
(void) fprintf(fp, "Usage: %s\n"
|
||||||
"\t[-v vdevs (default: %llu)]\n"
|
"\t[-v vdevs (default: %llu)]\n"
|
||||||
"\t[-s size_of_each_vdev (default: %s)]\n"
|
"\t[-s size_of_each_vdev (default: %s)]\n"
|
||||||
"\t[-a alignment_shift (default: %d) (use 0 for random)]\n"
|
"\t[-a alignment_shift (default: %d) (use 0 for random)]\n"
|
||||||
@ -364,6 +378,7 @@ usage(void)
|
|||||||
"\t[-T time] total run time (default: %llu sec)\n"
|
"\t[-T time] total run time (default: %llu sec)\n"
|
||||||
"\t[-P passtime] time per pass (default: %llu sec)\n"
|
"\t[-P passtime] time per pass (default: %llu sec)\n"
|
||||||
"\t[-z zil failure rate (default: fail every 2^%llu allocs)]\n"
|
"\t[-z zil failure rate (default: fail every 2^%llu allocs)]\n"
|
||||||
|
"\t[-h] (print help)\n"
|
||||||
"",
|
"",
|
||||||
cmdname,
|
cmdname,
|
||||||
(u_longlong_t)zopt_vdevs, /* -v */
|
(u_longlong_t)zopt_vdevs, /* -v */
|
||||||
@ -382,7 +397,7 @@ usage(void)
|
|||||||
(u_longlong_t)zopt_time, /* -T */
|
(u_longlong_t)zopt_time, /* -T */
|
||||||
(u_longlong_t)zopt_passtime, /* -P */
|
(u_longlong_t)zopt_passtime, /* -P */
|
||||||
(u_longlong_t)zio_zil_fail_shift); /* -z */
|
(u_longlong_t)zio_zil_fail_shift); /* -z */
|
||||||
exit(1);
|
exit(requested ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
@ -422,7 +437,7 @@ process_options(int argc, char **argv)
|
|||||||
zio_zil_fail_shift = 5;
|
zio_zil_fail_shift = 5;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv,
|
while ((opt = getopt(argc, argv,
|
||||||
"v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:z:")) != EOF) {
|
"v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:z:h")) != EOF) {
|
||||||
value = 0;
|
value = 0;
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'v':
|
case 'v':
|
||||||
@ -496,9 +511,12 @@ process_options(int argc, char **argv)
|
|||||||
case 'z':
|
case 'z':
|
||||||
zio_zil_fail_shift = MIN(value, 16);
|
zio_zil_fail_shift = MIN(value, 16);
|
||||||
break;
|
break;
|
||||||
|
case 'h':
|
||||||
|
usage(B_TRUE);
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage(B_FALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ enum {
|
|||||||
EZFS_POOLPROPS, /* couldn't retrieve pool props */
|
EZFS_POOLPROPS, /* couldn't retrieve pool props */
|
||||||
EZFS_POOL_NOTSUP, /* ops not supported for this type of pool */
|
EZFS_POOL_NOTSUP, /* ops not supported for this type of pool */
|
||||||
EZFS_POOL_INVALARG, /* invalid argument for this pool operation */
|
EZFS_POOL_INVALARG, /* invalid argument for this pool operation */
|
||||||
|
EZFS_NAMETOOLONG, /* dataset name is too long */
|
||||||
EZFS_UNKNOWN
|
EZFS_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,6 +193,7 @@ typedef enum {
|
|||||||
ZPOOL_STATUS_CORRUPT_DATA, /* data errors in user (meta)data */
|
ZPOOL_STATUS_CORRUPT_DATA, /* data errors in user (meta)data */
|
||||||
ZPOOL_STATUS_FAILING_DEV, /* device experiencing errors */
|
ZPOOL_STATUS_FAILING_DEV, /* device experiencing errors */
|
||||||
ZPOOL_STATUS_VERSION_NEWER, /* newer on-disk version */
|
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
|
* The following are not faults per se, but still an error possibly
|
||||||
|
@ -379,7 +379,7 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
|||||||
uint_t i, nspares;
|
uint_t i, nspares;
|
||||||
boolean_t config_seen;
|
boolean_t config_seen;
|
||||||
uint64_t best_txg;
|
uint64_t best_txg;
|
||||||
char *name;
|
char *name, *hostname;
|
||||||
zfs_cmd_t zc = { 0 };
|
zfs_cmd_t zc = { 0 };
|
||||||
uint64_t version, guid;
|
uint64_t version, guid;
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -388,6 +388,7 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
|||||||
nvlist_t **child = NULL;
|
nvlist_t **child = NULL;
|
||||||
uint_t c;
|
uint_t c;
|
||||||
boolean_t isactive;
|
boolean_t isactive;
|
||||||
|
uint64_t hostid;
|
||||||
|
|
||||||
if (nvlist_alloc(&ret, 0, 0) != 0)
|
if (nvlist_alloc(&ret, 0, 0) != 0)
|
||||||
goto nomem;
|
goto nomem;
|
||||||
@ -430,6 +431,8 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
|||||||
* pool guid
|
* pool guid
|
||||||
* name
|
* name
|
||||||
* pool state
|
* pool state
|
||||||
|
* hostid (if available)
|
||||||
|
* hostname (if available)
|
||||||
*/
|
*/
|
||||||
uint64_t state;
|
uint64_t state;
|
||||||
|
|
||||||
@ -453,6 +456,20 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
|||||||
if (nvlist_add_uint64(config,
|
if (nvlist_add_uint64(config,
|
||||||
ZPOOL_CONFIG_POOL_STATE, state) != 0)
|
ZPOOL_CONFIG_POOL_STATE, state) != 0)
|
||||||
goto nomem;
|
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;
|
config_seen = B_TRUE;
|
||||||
}
|
}
|
||||||
@ -621,6 +638,20 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
* Add this pool to the list of configs.
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
* CDDL HEADER END
|
* 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.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -43,6 +43,7 @@
|
|||||||
|
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "libzfs_impl.h"
|
#include "libzfs_impl.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -50,7 +51,7 @@
|
|||||||
* in libzfs.h. Note that there are some status results which go past the end
|
* 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.
|
* of this table, and hence have no associated message ID.
|
||||||
*/
|
*/
|
||||||
static char *msgid_table[] = {
|
static char *zfs_msgid_table[] = {
|
||||||
"ZFS-8000-14",
|
"ZFS-8000-14",
|
||||||
"ZFS-8000-2Q",
|
"ZFS-8000-2Q",
|
||||||
"ZFS-8000-3C",
|
"ZFS-8000-3C",
|
||||||
@ -60,7 +61,8 @@ static char *msgid_table[] = {
|
|||||||
"ZFS-8000-72",
|
"ZFS-8000-72",
|
||||||
"ZFS-8000-8A",
|
"ZFS-8000-8A",
|
||||||
"ZFS-8000-9P",
|
"ZFS-8000-9P",
|
||||||
"ZFS-8000-A5"
|
"ZFS-8000-A5",
|
||||||
|
"ZFS-8000-EY"
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -69,7 +71,7 @@ static char *msgid_table[] = {
|
|||||||
* and the article referred to by 'zpool status' must match that indicated by
|
* 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.
|
* 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-14",
|
||||||
"ZFS-8000-D3", /* overridden */
|
"ZFS-8000-D3", /* overridden */
|
||||||
"ZFS-8000-D3", /* overridden */
|
"ZFS-8000-D3", /* overridden */
|
||||||
@ -82,7 +84,7 @@ static char *msgid_table_active[] = {
|
|||||||
"ZFS-8000-CS", /* overridden */
|
"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 */
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
@ -178,6 +180,8 @@ check_status(nvlist_t *config, boolean_t isimport)
|
|||||||
uint_t vsc;
|
uint_t vsc;
|
||||||
uint64_t nerr;
|
uint64_t nerr;
|
||||||
uint64_t version;
|
uint64_t version;
|
||||||
|
uint64_t stateval;
|
||||||
|
uint64_t hostid = 0;
|
||||||
|
|
||||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
|
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
|
||||||
&version) == 0);
|
&version) == 0);
|
||||||
@ -185,6 +189,16 @@ check_status(nvlist_t *config, boolean_t isimport)
|
|||||||
&nvroot) == 0);
|
&nvroot) == 0);
|
||||||
verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
|
verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
|
||||||
(uint64_t **)&vs, &vsc) == 0);
|
(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.
|
* Newer on-disk version.
|
||||||
@ -270,7 +284,7 @@ zpool_get_status(zpool_handle_t *zhp, char **msgid)
|
|||||||
if (ret >= NMSGID)
|
if (ret >= NMSGID)
|
||||||
*msgid = NULL;
|
*msgid = NULL;
|
||||||
else
|
else
|
||||||
*msgid = msgid_table_active[ret];
|
*msgid = zfs_msgid_table_active[ret];
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@ -283,7 +297,7 @@ zpool_import_status(nvlist_t *config, char **msgid)
|
|||||||
if (ret >= NMSGID)
|
if (ret >= NMSGID)
|
||||||
*msgid = NULL;
|
*msgid = NULL;
|
||||||
else
|
else
|
||||||
*msgid = msgid_table[ret];
|
*msgid = zfs_msgid_table[ret];
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,8 @@ libzfs_error_description(libzfs_handle_t *hdl)
|
|||||||
case EZFS_POOL_INVALARG:
|
case EZFS_POOL_INVALARG:
|
||||||
return (dgettext(TEXT_DOMAIN, "invalid argument for "
|
return (dgettext(TEXT_DOMAIN, "invalid argument for "
|
||||||
"this pool operation"));
|
"this pool operation"));
|
||||||
|
case EZFS_NAMETOOLONG:
|
||||||
|
return (dgettext(TEXT_DOMAIN, "dataset name is too long"));
|
||||||
case EZFS_UNKNOWN:
|
case EZFS_UNKNOWN:
|
||||||
return (dgettext(TEXT_DOMAIN, "unknown error"));
|
return (dgettext(TEXT_DOMAIN, "unknown error"));
|
||||||
default:
|
default:
|
||||||
@ -306,6 +308,11 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
|
|||||||
"dataset is busy"));
|
"dataset is busy"));
|
||||||
zfs_verror(hdl, EZFS_BUSY, fmt, ap);
|
zfs_verror(hdl, EZFS_BUSY, fmt, ap);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ENAMETOOLONG:
|
||||||
|
zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
zfs_error_aux(hdl, strerror(errno));
|
zfs_error_aux(hdl, strerror(errno));
|
||||||
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
|
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <sys/processor.h>
|
#include <sys/processor.h>
|
||||||
#include <sys/zfs_context.h>
|
#include <sys/zfs_context.h>
|
||||||
#include <sys/zmod.h>
|
#include <sys/zmod.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Emulation of kernel services in userland.
|
* Emulation of kernel services in userland.
|
||||||
@ -45,6 +46,11 @@
|
|||||||
int hz = 119; /* frequency when using gethrtime() >> 23 for lbolt */
|
int hz = 119; /* frequency when using gethrtime() >> 23 for lbolt */
|
||||||
uint64_t physmem;
|
uint64_t physmem;
|
||||||
vnode_t *rootdir = (vnode_t *)0xabcd1234;
|
vnode_t *rootdir = (vnode_t *)0xabcd1234;
|
||||||
|
char hw_serial[11];
|
||||||
|
|
||||||
|
struct utsname utsname = {
|
||||||
|
"userland", "libzpool", "1", "1", "na"
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =========================================================================
|
* =========================================================================
|
||||||
@ -770,6 +776,17 @@ random_get_pseudo_bytes(uint8_t *ptr, size_t len)
|
|||||||
return (random_get_bytes_common(ptr, len, "/dev/urandom"));
|
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
|
* kernel emulation setup & teardown
|
||||||
@ -795,6 +812,8 @@ kernel_init(int mode)
|
|||||||
dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
|
dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
|
||||||
(double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
|
(double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
|
||||||
|
|
||||||
|
snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid());
|
||||||
|
|
||||||
spa_init(mode);
|
spa_init(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,6 +436,14 @@ typedef struct callb_cpr {
|
|||||||
#define zone_dataset_visible(x, y) (1)
|
#define zone_dataset_visible(x, y) (1)
|
||||||
#define INGLOBALZONE(z) (1)
|
#define INGLOBALZONE(z) (1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hostname information
|
||||||
|
*/
|
||||||
|
extern struct utsname utsname;
|
||||||
|
extern char hw_serial[];
|
||||||
|
extern int ddi_strtoul(const char *str, char **nptr, int base,
|
||||||
|
unsigned long *result);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1082,6 +1082,10 @@ show_import(nvlist_t *config)
|
|||||||
"incompatible version.\n"));
|
"incompatible version.\n"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ZPOOL_STATUS_HOSTID_MISMATCH:
|
||||||
|
(void) printf(gettext("status: The pool was last accessed by "
|
||||||
|
"another system.\n"));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* No other status can be seen when importing pools.
|
* No other status can be seen when importing pools.
|
||||||
@ -1098,6 +1102,10 @@ show_import(nvlist_t *config)
|
|||||||
"imported using its name or numeric identifier, "
|
"imported using its name or numeric identifier, "
|
||||||
"though\n\tsome features will not be available "
|
"though\n\tsome features will not be available "
|
||||||
"without an explicit 'zpool upgrade'.\n"));
|
"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
|
else
|
||||||
(void) printf(gettext("action: The pool can be "
|
(void) printf(gettext("action: The pool can be "
|
||||||
"imported using its name or numeric "
|
"imported using its name or numeric "
|
||||||
@ -1187,10 +1195,37 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
|||||||
"is formatted using a newer ZFS version\n"), name);
|
"is formatted using a newer ZFS version\n"), name);
|
||||||
return (1);
|
return (1);
|
||||||
} else if (state != POOL_STATE_EXPORTED && !force) {
|
} else if (state != POOL_STATE_EXPORTED && !force) {
|
||||||
(void) fprintf(stderr, gettext("cannot import '%s': pool "
|
uint64_t hostid;
|
||||||
"may be in use from other system\n"), name);
|
|
||||||
(void) fprintf(stderr, gettext("use '-f' to import anyway\n"));
|
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
|
||||||
return (1);
|
&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)
|
if (zpool_import(g_zfs, config, newname, altroot) != 0)
|
||||||
|
@ -246,6 +246,8 @@ extern uint16_t zio_zil_fail_shift;
|
|||||||
#define ZTEST_DIROBJ_BLOCKSIZE (1 << 10)
|
#define ZTEST_DIROBJ_BLOCKSIZE (1 << 10)
|
||||||
#define ZTEST_DIRSIZE 256
|
#define ZTEST_DIRSIZE 256
|
||||||
|
|
||||||
|
static void usage(boolean_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These libumem hooks provide a reasonable set of defaults for the allocator's
|
* These libumem hooks provide a reasonable set of defaults for the allocator's
|
||||||
* debugging facilities.
|
* debugging facilities.
|
||||||
@ -303,13 +305,17 @@ str2shift(const char *buf)
|
|||||||
if (toupper(buf[0]) == ends[i])
|
if (toupper(buf[0]) == ends[i])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == strlen(ends))
|
if (i == strlen(ends)) {
|
||||||
fatal(0, "invalid bytes suffix: %s", buf);
|
(void) fprintf(stderr, "ztest: invalid bytes suffix: %s\n",
|
||||||
|
buf);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0')) {
|
if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0')) {
|
||||||
return (10*i);
|
return (10*i);
|
||||||
}
|
}
|
||||||
fatal(0, "invalid bytes suffix: %s", buf);
|
(void) fprintf(stderr, "ztest: invalid bytes suffix: %s\n", buf);
|
||||||
return (-1);
|
usage(B_FALSE);
|
||||||
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
@ -320,32 +326,40 @@ nicenumtoull(const char *buf)
|
|||||||
|
|
||||||
val = strtoull(buf, &end, 0);
|
val = strtoull(buf, &end, 0);
|
||||||
if (end == buf) {
|
if (end == buf) {
|
||||||
fatal(0, "bad numeric value: %s", buf);
|
(void) fprintf(stderr, "ztest: bad numeric value: %s\n", buf);
|
||||||
|
usage(B_FALSE);
|
||||||
} else if (end[0] == '.') {
|
} else if (end[0] == '.') {
|
||||||
double fval = strtod(buf, &end);
|
double fval = strtod(buf, &end);
|
||||||
fval *= pow(2, str2shift(end));
|
fval *= pow(2, str2shift(end));
|
||||||
if (fval > UINT64_MAX)
|
if (fval > UINT64_MAX) {
|
||||||
fatal(0, "value too large: %s", buf);
|
(void) fprintf(stderr, "ztest: value too large: %s\n",
|
||||||
|
buf);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
val = (uint64_t)fval;
|
val = (uint64_t)fval;
|
||||||
} else {
|
} else {
|
||||||
int shift = str2shift(end);
|
int shift = str2shift(end);
|
||||||
if (shift >= 64 || (val << shift) >> shift != val)
|
if (shift >= 64 || (val << shift) >> shift != val) {
|
||||||
fatal(0, "value too large: %s", buf);
|
(void) fprintf(stderr, "ztest: value too large: %s\n",
|
||||||
|
buf);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
val <<= shift;
|
val <<= shift;
|
||||||
}
|
}
|
||||||
return (val);
|
return (val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(boolean_t requested)
|
||||||
{
|
{
|
||||||
char nice_vdev_size[10];
|
char nice_vdev_size[10];
|
||||||
char nice_gang_bang[10];
|
char nice_gang_bang[10];
|
||||||
|
FILE *fp = requested ? stdout : stderr;
|
||||||
|
|
||||||
nicenum(zopt_vdev_size, nice_vdev_size);
|
nicenum(zopt_vdev_size, nice_vdev_size);
|
||||||
nicenum(zio_gang_bang, nice_gang_bang);
|
nicenum(zio_gang_bang, nice_gang_bang);
|
||||||
|
|
||||||
(void) printf("Usage: %s\n"
|
(void) fprintf(fp, "Usage: %s\n"
|
||||||
"\t[-v vdevs (default: %llu)]\n"
|
"\t[-v vdevs (default: %llu)]\n"
|
||||||
"\t[-s size_of_each_vdev (default: %s)]\n"
|
"\t[-s size_of_each_vdev (default: %s)]\n"
|
||||||
"\t[-a alignment_shift (default: %d) (use 0 for random)]\n"
|
"\t[-a alignment_shift (default: %d) (use 0 for random)]\n"
|
||||||
@ -364,6 +378,7 @@ usage(void)
|
|||||||
"\t[-T time] total run time (default: %llu sec)\n"
|
"\t[-T time] total run time (default: %llu sec)\n"
|
||||||
"\t[-P passtime] time per pass (default: %llu sec)\n"
|
"\t[-P passtime] time per pass (default: %llu sec)\n"
|
||||||
"\t[-z zil failure rate (default: fail every 2^%llu allocs)]\n"
|
"\t[-z zil failure rate (default: fail every 2^%llu allocs)]\n"
|
||||||
|
"\t[-h] (print help)\n"
|
||||||
"",
|
"",
|
||||||
cmdname,
|
cmdname,
|
||||||
(u_longlong_t)zopt_vdevs, /* -v */
|
(u_longlong_t)zopt_vdevs, /* -v */
|
||||||
@ -382,7 +397,7 @@ usage(void)
|
|||||||
(u_longlong_t)zopt_time, /* -T */
|
(u_longlong_t)zopt_time, /* -T */
|
||||||
(u_longlong_t)zopt_passtime, /* -P */
|
(u_longlong_t)zopt_passtime, /* -P */
|
||||||
(u_longlong_t)zio_zil_fail_shift); /* -z */
|
(u_longlong_t)zio_zil_fail_shift); /* -z */
|
||||||
exit(1);
|
exit(requested ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
@ -422,7 +437,7 @@ process_options(int argc, char **argv)
|
|||||||
zio_zil_fail_shift = 5;
|
zio_zil_fail_shift = 5;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv,
|
while ((opt = getopt(argc, argv,
|
||||||
"v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:z:")) != EOF) {
|
"v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:z:h")) != EOF) {
|
||||||
value = 0;
|
value = 0;
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'v':
|
case 'v':
|
||||||
@ -496,9 +511,12 @@ process_options(int argc, char **argv)
|
|||||||
case 'z':
|
case 'z':
|
||||||
zio_zil_fail_shift = MIN(value, 16);
|
zio_zil_fail_shift = MIN(value, 16);
|
||||||
break;
|
break;
|
||||||
|
case 'h':
|
||||||
|
usage(B_TRUE);
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage(B_FALSE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ enum {
|
|||||||
EZFS_POOLPROPS, /* couldn't retrieve pool props */
|
EZFS_POOLPROPS, /* couldn't retrieve pool props */
|
||||||
EZFS_POOL_NOTSUP, /* ops not supported for this type of pool */
|
EZFS_POOL_NOTSUP, /* ops not supported for this type of pool */
|
||||||
EZFS_POOL_INVALARG, /* invalid argument for this pool operation */
|
EZFS_POOL_INVALARG, /* invalid argument for this pool operation */
|
||||||
|
EZFS_NAMETOOLONG, /* dataset name is too long */
|
||||||
EZFS_UNKNOWN
|
EZFS_UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,6 +193,7 @@ typedef enum {
|
|||||||
ZPOOL_STATUS_CORRUPT_DATA, /* data errors in user (meta)data */
|
ZPOOL_STATUS_CORRUPT_DATA, /* data errors in user (meta)data */
|
||||||
ZPOOL_STATUS_FAILING_DEV, /* device experiencing errors */
|
ZPOOL_STATUS_FAILING_DEV, /* device experiencing errors */
|
||||||
ZPOOL_STATUS_VERSION_NEWER, /* newer on-disk version */
|
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
|
* The following are not faults per se, but still an error possibly
|
||||||
|
@ -379,7 +379,7 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
|||||||
uint_t i, nspares;
|
uint_t i, nspares;
|
||||||
boolean_t config_seen;
|
boolean_t config_seen;
|
||||||
uint64_t best_txg;
|
uint64_t best_txg;
|
||||||
char *name;
|
char *name, *hostname;
|
||||||
zfs_cmd_t zc = { 0 };
|
zfs_cmd_t zc = { 0 };
|
||||||
uint64_t version, guid;
|
uint64_t version, guid;
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -388,6 +388,7 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
|||||||
nvlist_t **child = NULL;
|
nvlist_t **child = NULL;
|
||||||
uint_t c;
|
uint_t c;
|
||||||
boolean_t isactive;
|
boolean_t isactive;
|
||||||
|
uint64_t hostid;
|
||||||
|
|
||||||
if (nvlist_alloc(&ret, 0, 0) != 0)
|
if (nvlist_alloc(&ret, 0, 0) != 0)
|
||||||
goto nomem;
|
goto nomem;
|
||||||
@ -430,6 +431,8 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
|||||||
* pool guid
|
* pool guid
|
||||||
* name
|
* name
|
||||||
* pool state
|
* pool state
|
||||||
|
* hostid (if available)
|
||||||
|
* hostname (if available)
|
||||||
*/
|
*/
|
||||||
uint64_t state;
|
uint64_t state;
|
||||||
|
|
||||||
@ -453,6 +456,20 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
|||||||
if (nvlist_add_uint64(config,
|
if (nvlist_add_uint64(config,
|
||||||
ZPOOL_CONFIG_POOL_STATE, state) != 0)
|
ZPOOL_CONFIG_POOL_STATE, state) != 0)
|
||||||
goto nomem;
|
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;
|
config_seen = B_TRUE;
|
||||||
}
|
}
|
||||||
@ -621,6 +638,20 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
* Add this pool to the list of configs.
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
* CDDL HEADER END
|
* 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.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -43,6 +43,7 @@
|
|||||||
|
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "libzfs_impl.h"
|
#include "libzfs_impl.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -50,7 +51,7 @@
|
|||||||
* in libzfs.h. Note that there are some status results which go past the end
|
* 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.
|
* of this table, and hence have no associated message ID.
|
||||||
*/
|
*/
|
||||||
static char *msgid_table[] = {
|
static char *zfs_msgid_table[] = {
|
||||||
"ZFS-8000-14",
|
"ZFS-8000-14",
|
||||||
"ZFS-8000-2Q",
|
"ZFS-8000-2Q",
|
||||||
"ZFS-8000-3C",
|
"ZFS-8000-3C",
|
||||||
@ -60,7 +61,8 @@ static char *msgid_table[] = {
|
|||||||
"ZFS-8000-72",
|
"ZFS-8000-72",
|
||||||
"ZFS-8000-8A",
|
"ZFS-8000-8A",
|
||||||
"ZFS-8000-9P",
|
"ZFS-8000-9P",
|
||||||
"ZFS-8000-A5"
|
"ZFS-8000-A5",
|
||||||
|
"ZFS-8000-EY"
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -69,7 +71,7 @@ static char *msgid_table[] = {
|
|||||||
* and the article referred to by 'zpool status' must match that indicated by
|
* 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.
|
* 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-14",
|
||||||
"ZFS-8000-D3", /* overridden */
|
"ZFS-8000-D3", /* overridden */
|
||||||
"ZFS-8000-D3", /* overridden */
|
"ZFS-8000-D3", /* overridden */
|
||||||
@ -82,7 +84,7 @@ static char *msgid_table_active[] = {
|
|||||||
"ZFS-8000-CS", /* overridden */
|
"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 */
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
@ -178,6 +180,8 @@ check_status(nvlist_t *config, boolean_t isimport)
|
|||||||
uint_t vsc;
|
uint_t vsc;
|
||||||
uint64_t nerr;
|
uint64_t nerr;
|
||||||
uint64_t version;
|
uint64_t version;
|
||||||
|
uint64_t stateval;
|
||||||
|
uint64_t hostid = 0;
|
||||||
|
|
||||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
|
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
|
||||||
&version) == 0);
|
&version) == 0);
|
||||||
@ -185,6 +189,16 @@ check_status(nvlist_t *config, boolean_t isimport)
|
|||||||
&nvroot) == 0);
|
&nvroot) == 0);
|
||||||
verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
|
verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
|
||||||
(uint64_t **)&vs, &vsc) == 0);
|
(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.
|
* Newer on-disk version.
|
||||||
@ -270,7 +284,7 @@ zpool_get_status(zpool_handle_t *zhp, char **msgid)
|
|||||||
if (ret >= NMSGID)
|
if (ret >= NMSGID)
|
||||||
*msgid = NULL;
|
*msgid = NULL;
|
||||||
else
|
else
|
||||||
*msgid = msgid_table_active[ret];
|
*msgid = zfs_msgid_table_active[ret];
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@ -283,7 +297,7 @@ zpool_import_status(nvlist_t *config, char **msgid)
|
|||||||
if (ret >= NMSGID)
|
if (ret >= NMSGID)
|
||||||
*msgid = NULL;
|
*msgid = NULL;
|
||||||
else
|
else
|
||||||
*msgid = msgid_table[ret];
|
*msgid = zfs_msgid_table[ret];
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,8 @@ libzfs_error_description(libzfs_handle_t *hdl)
|
|||||||
case EZFS_POOL_INVALARG:
|
case EZFS_POOL_INVALARG:
|
||||||
return (dgettext(TEXT_DOMAIN, "invalid argument for "
|
return (dgettext(TEXT_DOMAIN, "invalid argument for "
|
||||||
"this pool operation"));
|
"this pool operation"));
|
||||||
|
case EZFS_NAMETOOLONG:
|
||||||
|
return (dgettext(TEXT_DOMAIN, "dataset name is too long"));
|
||||||
case EZFS_UNKNOWN:
|
case EZFS_UNKNOWN:
|
||||||
return (dgettext(TEXT_DOMAIN, "unknown error"));
|
return (dgettext(TEXT_DOMAIN, "unknown error"));
|
||||||
default:
|
default:
|
||||||
@ -306,6 +308,11 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
|
|||||||
"dataset is busy"));
|
"dataset is busy"));
|
||||||
zfs_verror(hdl, EZFS_BUSY, fmt, ap);
|
zfs_verror(hdl, EZFS_BUSY, fmt, ap);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ENAMETOOLONG:
|
||||||
|
zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
zfs_error_aux(hdl, strerror(errno));
|
zfs_error_aux(hdl, strerror(errno));
|
||||||
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
|
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <sys/processor.h>
|
#include <sys/processor.h>
|
||||||
#include <sys/zfs_context.h>
|
#include <sys/zfs_context.h>
|
||||||
#include <sys/zmod.h>
|
#include <sys/zmod.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Emulation of kernel services in userland.
|
* Emulation of kernel services in userland.
|
||||||
@ -45,6 +46,11 @@
|
|||||||
int hz = 119; /* frequency when using gethrtime() >> 23 for lbolt */
|
int hz = 119; /* frequency when using gethrtime() >> 23 for lbolt */
|
||||||
uint64_t physmem;
|
uint64_t physmem;
|
||||||
vnode_t *rootdir = (vnode_t *)0xabcd1234;
|
vnode_t *rootdir = (vnode_t *)0xabcd1234;
|
||||||
|
char hw_serial[11];
|
||||||
|
|
||||||
|
struct utsname utsname = {
|
||||||
|
"userland", "libzpool", "1", "1", "na"
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =========================================================================
|
* =========================================================================
|
||||||
@ -770,6 +776,17 @@ random_get_pseudo_bytes(uint8_t *ptr, size_t len)
|
|||||||
return (random_get_bytes_common(ptr, len, "/dev/urandom"));
|
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
|
* kernel emulation setup & teardown
|
||||||
@ -795,6 +812,8 @@ kernel_init(int mode)
|
|||||||
dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
|
dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
|
||||||
(double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
|
(double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
|
||||||
|
|
||||||
|
snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid());
|
||||||
|
|
||||||
spa_init(mode);
|
spa_init(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,6 +436,14 @@ typedef struct callb_cpr {
|
|||||||
#define zone_dataset_visible(x, y) (1)
|
#define zone_dataset_visible(x, y) (1)
|
||||||
#define INGLOBALZONE(z) (1)
|
#define INGLOBALZONE(z) (1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hostname information
|
||||||
|
*/
|
||||||
|
extern struct utsname utsname;
|
||||||
|
extern char hw_serial[];
|
||||||
|
extern int ddi_strtoul(const char *str, char **nptr, int base,
|
||||||
|
unsigned long *result);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
55
sys/cddl/compat/opensolaris/kern/opensolaris_misc.c
Normal file
55
sys/cddl/compat/opensolaris/kern/opensolaris_misc.c
Normal file
@ -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);
|
||||||
|
}
|
40
sys/cddl/compat/opensolaris/sys/misc.h
Normal file
40
sys/cddl/compat/opensolaris/sys/misc.h
Normal file
@ -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_ */
|
@ -948,7 +948,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
|
|||||||
objset_t *os;
|
objset_t *os;
|
||||||
uint64_t snapobj;
|
uint64_t snapobj;
|
||||||
zap_cursor_t zc;
|
zap_cursor_t zc;
|
||||||
zap_attribute_t attr;
|
zap_attribute_t *attr;
|
||||||
char *child;
|
char *child;
|
||||||
int do_self, err;
|
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 */
|
/* NB: the $MOS dir doesn't have a head dataset */
|
||||||
do_self = (dd->dd_phys->dd_head_dataset_obj != 0);
|
do_self = (dd->dd_phys->dd_head_dataset_obj != 0);
|
||||||
|
attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterate over all children.
|
* 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) {
|
if (flags & DS_FIND_CHILDREN) {
|
||||||
for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset,
|
for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset,
|
||||||
dd->dd_phys->dd_child_dir_zapobj);
|
dd->dd_phys->dd_child_dir_zapobj);
|
||||||
zap_cursor_retrieve(&zc, &attr) == 0;
|
zap_cursor_retrieve(&zc, attr) == 0;
|
||||||
(void) zap_cursor_advance(&zc)) {
|
(void) zap_cursor_advance(&zc)) {
|
||||||
ASSERT(attr.za_integer_length == sizeof (uint64_t));
|
ASSERT(attr->za_integer_length == sizeof (uint64_t));
|
||||||
ASSERT(attr.za_num_integers == 1);
|
ASSERT(attr->za_num_integers == 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No separating '/' because parent's name ends in /.
|
* 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 */
|
/* XXX could probably just use name here */
|
||||||
dsl_dir_name(dd, child);
|
dsl_dir_name(dd, child);
|
||||||
(void) strcat(child, "/");
|
(void) strcat(child, "/");
|
||||||
(void) strcat(child, attr.za_name);
|
(void) strcat(child, attr->za_name);
|
||||||
err = dmu_objset_find(child, func, arg, flags);
|
err = dmu_objset_find(child, func, arg, flags);
|
||||||
kmem_free(child, MAXPATHLEN);
|
kmem_free(child, MAXPATHLEN);
|
||||||
if (err)
|
if (err)
|
||||||
@ -987,6 +988,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
|
|||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
dsl_dir_close(dd, FTAG);
|
dsl_dir_close(dd, FTAG);
|
||||||
|
kmem_free(attr, sizeof (zap_attribute_t));
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1002,16 +1004,16 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
|
|||||||
dmu_objset_close(os);
|
dmu_objset_close(os);
|
||||||
|
|
||||||
for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, snapobj);
|
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)) {
|
(void) zap_cursor_advance(&zc)) {
|
||||||
ASSERT(attr.za_integer_length == sizeof (uint64_t));
|
ASSERT(attr->za_integer_length == sizeof (uint64_t));
|
||||||
ASSERT(attr.za_num_integers == 1);
|
ASSERT(attr->za_num_integers == 1);
|
||||||
|
|
||||||
child = kmem_alloc(MAXPATHLEN, KM_SLEEP);
|
child = kmem_alloc(MAXPATHLEN, KM_SLEEP);
|
||||||
/* XXX could probably just use name here */
|
/* XXX could probably just use name here */
|
||||||
dsl_dir_name(dd, child);
|
dsl_dir_name(dd, child);
|
||||||
(void) strcat(child, "@");
|
(void) strcat(child, "@");
|
||||||
(void) strcat(child, attr.za_name);
|
(void) strcat(child, attr->za_name);
|
||||||
err = func(child, arg);
|
err = func(child, arg);
|
||||||
kmem_free(child, MAXPATHLEN);
|
kmem_free(child, MAXPATHLEN);
|
||||||
if (err)
|
if (err)
|
||||||
@ -1021,6 +1023,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dsl_dir_close(dd, FTAG);
|
dsl_dir_close(dd, FTAG);
|
||||||
|
kmem_free(attr, sizeof (zap_attribute_t));
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return (err);
|
return (err);
|
||||||
|
@ -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
|
void
|
||||||
dsl_dataset_close(dsl_dataset_t *ds, int mode, void *tag)
|
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)
|
if (err != ENOENT)
|
||||||
return (err);
|
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;
|
ds->ds_trysnap_txg = tx->tx_txg;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
* CDDL HEADER END
|
* 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.
|
* 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
|
int
|
||||||
dsl_dir_is_private(dsl_dir_t *dd)
|
dsl_dir_is_private(dsl_dir_t *dd)
|
||||||
{
|
{
|
||||||
|
@ -579,6 +579,7 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig)
|
|||||||
|
|
||||||
if (!mosconfig) {
|
if (!mosconfig) {
|
||||||
nvlist_t *newconfig;
|
nvlist_t *newconfig;
|
||||||
|
uint64_t hostid;
|
||||||
|
|
||||||
if (load_nvlist(spa, spa->spa_config_object, &newconfig) != 0) {
|
if (load_nvlist(spa, spa->spa_config_object, &newconfig) != 0) {
|
||||||
vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
|
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;
|
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_config_set(spa, newconfig);
|
||||||
spa_unload(spa);
|
spa_unload(spa);
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
@ -1366,6 +1388,8 @@ spa_tryimport(nvlist_t *tryconfig)
|
|||||||
poolname) == 0);
|
poolname) == 0);
|
||||||
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE,
|
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE,
|
||||||
state) == 0);
|
state) == 0);
|
||||||
|
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TIMESTAMP,
|
||||||
|
spa->spa_uberblock.ub_timestamp) == 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add the list of hot spares.
|
* Add the list of hot spares.
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <sys/fs/zfs.h>
|
#include <sys/fs/zfs.h>
|
||||||
#include <sys/vdev_impl.h>
|
#include <sys/vdev_impl.h>
|
||||||
#include <sys/zfs_ioctl.h>
|
#include <sys/zfs_ioctl.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
#include <sys/kobj.h>
|
#include <sys/kobj.h>
|
||||||
#endif
|
#endif
|
||||||
@ -268,6 +269,7 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
|
|||||||
{
|
{
|
||||||
nvlist_t *config, *nvroot;
|
nvlist_t *config, *nvroot;
|
||||||
vdev_t *rvd = spa->spa_root_vdev;
|
vdev_t *rvd = spa->spa_root_vdev;
|
||||||
|
unsigned long hostid = 0;
|
||||||
|
|
||||||
ASSERT(spa_config_held(spa, RW_READER));
|
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);
|
txg) == 0);
|
||||||
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
||||||
spa_guid(spa)) == 0);
|
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) {
|
if (vd != rvd) {
|
||||||
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID,
|
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID,
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
* CDDL HEADER END
|
* 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.
|
* 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,
|
int dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj,
|
||||||
const char *tail, void *tag, dsl_dir_t **);
|
const char *tail, void *tag, dsl_dir_t **);
|
||||||
void dsl_dir_name(dsl_dir_t *dd, char *buf);
|
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);
|
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);
|
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);
|
void dsl_dir_create_root(objset_t *mos, uint64_t *ddobjp, dmu_tx_t *tx);
|
||||||
|
@ -46,7 +46,6 @@ extern "C" {
|
|||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <sys/taskq.h>
|
#include <sys/taskq.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/kobj.h>
|
|
||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
#include <sys/rwlock.h>
|
#include <sys/rwlock.h>
|
||||||
@ -77,6 +76,7 @@ extern "C" {
|
|||||||
#include <sys/policy.h>
|
#include <sys/policy.h>
|
||||||
#include <sys/zone.h>
|
#include <sys/zone.h>
|
||||||
#include <sys/eventhandler.h>
|
#include <sys/eventhandler.h>
|
||||||
|
#include <sys/misc.h>
|
||||||
#include <sys/zfs_debug.h>
|
#include <sys/zfs_debug.h>
|
||||||
|
|
||||||
#include <machine/stdarg.h>
|
#include <machine/stdarg.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_SPARES "spares"
|
||||||
#define ZPOOL_CONFIG_IS_SPARE "is_spare"
|
#define ZPOOL_CONFIG_IS_SPARE "is_spare"
|
||||||
#define ZPOOL_CONFIG_NPARITY "nparity"
|
#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_ROOT "root"
|
||||||
#define VDEV_TYPE_MIRROR "mirror"
|
#define VDEV_TYPE_MIRROR "mirror"
|
||||||
|
55
sys/compat/opensolaris/kern/opensolaris_misc.c
Normal file
55
sys/compat/opensolaris/kern/opensolaris_misc.c
Normal file
@ -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);
|
||||||
|
}
|
40
sys/compat/opensolaris/sys/misc.h
Normal file
40
sys/compat/opensolaris/sys/misc.h
Normal file
@ -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_ */
|
@ -948,7 +948,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
|
|||||||
objset_t *os;
|
objset_t *os;
|
||||||
uint64_t snapobj;
|
uint64_t snapobj;
|
||||||
zap_cursor_t zc;
|
zap_cursor_t zc;
|
||||||
zap_attribute_t attr;
|
zap_attribute_t *attr;
|
||||||
char *child;
|
char *child;
|
||||||
int do_self, err;
|
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 */
|
/* NB: the $MOS dir doesn't have a head dataset */
|
||||||
do_self = (dd->dd_phys->dd_head_dataset_obj != 0);
|
do_self = (dd->dd_phys->dd_head_dataset_obj != 0);
|
||||||
|
attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterate over all children.
|
* 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) {
|
if (flags & DS_FIND_CHILDREN) {
|
||||||
for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset,
|
for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset,
|
||||||
dd->dd_phys->dd_child_dir_zapobj);
|
dd->dd_phys->dd_child_dir_zapobj);
|
||||||
zap_cursor_retrieve(&zc, &attr) == 0;
|
zap_cursor_retrieve(&zc, attr) == 0;
|
||||||
(void) zap_cursor_advance(&zc)) {
|
(void) zap_cursor_advance(&zc)) {
|
||||||
ASSERT(attr.za_integer_length == sizeof (uint64_t));
|
ASSERT(attr->za_integer_length == sizeof (uint64_t));
|
||||||
ASSERT(attr.za_num_integers == 1);
|
ASSERT(attr->za_num_integers == 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No separating '/' because parent's name ends in /.
|
* 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 */
|
/* XXX could probably just use name here */
|
||||||
dsl_dir_name(dd, child);
|
dsl_dir_name(dd, child);
|
||||||
(void) strcat(child, "/");
|
(void) strcat(child, "/");
|
||||||
(void) strcat(child, attr.za_name);
|
(void) strcat(child, attr->za_name);
|
||||||
err = dmu_objset_find(child, func, arg, flags);
|
err = dmu_objset_find(child, func, arg, flags);
|
||||||
kmem_free(child, MAXPATHLEN);
|
kmem_free(child, MAXPATHLEN);
|
||||||
if (err)
|
if (err)
|
||||||
@ -987,6 +988,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
|
|||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
dsl_dir_close(dd, FTAG);
|
dsl_dir_close(dd, FTAG);
|
||||||
|
kmem_free(attr, sizeof (zap_attribute_t));
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1002,16 +1004,16 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
|
|||||||
dmu_objset_close(os);
|
dmu_objset_close(os);
|
||||||
|
|
||||||
for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, snapobj);
|
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)) {
|
(void) zap_cursor_advance(&zc)) {
|
||||||
ASSERT(attr.za_integer_length == sizeof (uint64_t));
|
ASSERT(attr->za_integer_length == sizeof (uint64_t));
|
||||||
ASSERT(attr.za_num_integers == 1);
|
ASSERT(attr->za_num_integers == 1);
|
||||||
|
|
||||||
child = kmem_alloc(MAXPATHLEN, KM_SLEEP);
|
child = kmem_alloc(MAXPATHLEN, KM_SLEEP);
|
||||||
/* XXX could probably just use name here */
|
/* XXX could probably just use name here */
|
||||||
dsl_dir_name(dd, child);
|
dsl_dir_name(dd, child);
|
||||||
(void) strcat(child, "@");
|
(void) strcat(child, "@");
|
||||||
(void) strcat(child, attr.za_name);
|
(void) strcat(child, attr->za_name);
|
||||||
err = func(child, arg);
|
err = func(child, arg);
|
||||||
kmem_free(child, MAXPATHLEN);
|
kmem_free(child, MAXPATHLEN);
|
||||||
if (err)
|
if (err)
|
||||||
@ -1021,6 +1023,7 @@ dmu_objset_find(char *name, int func(char *, void *), void *arg, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dsl_dir_close(dd, FTAG);
|
dsl_dir_close(dd, FTAG);
|
||||||
|
kmem_free(attr, sizeof (zap_attribute_t));
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return (err);
|
return (err);
|
||||||
|
@ -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
|
void
|
||||||
dsl_dataset_close(dsl_dataset_t *ds, int mode, void *tag)
|
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)
|
if (err != ENOENT)
|
||||||
return (err);
|
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;
|
ds->ds_trysnap_txg = tx->tx_txg;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
* CDDL HEADER END
|
* 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.
|
* 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
|
int
|
||||||
dsl_dir_is_private(dsl_dir_t *dd)
|
dsl_dir_is_private(dsl_dir_t *dd)
|
||||||
{
|
{
|
||||||
|
@ -579,6 +579,7 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig)
|
|||||||
|
|
||||||
if (!mosconfig) {
|
if (!mosconfig) {
|
||||||
nvlist_t *newconfig;
|
nvlist_t *newconfig;
|
||||||
|
uint64_t hostid;
|
||||||
|
|
||||||
if (load_nvlist(spa, spa->spa_config_object, &newconfig) != 0) {
|
if (load_nvlist(spa, spa->spa_config_object, &newconfig) != 0) {
|
||||||
vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
|
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;
|
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_config_set(spa, newconfig);
|
||||||
spa_unload(spa);
|
spa_unload(spa);
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
@ -1366,6 +1388,8 @@ spa_tryimport(nvlist_t *tryconfig)
|
|||||||
poolname) == 0);
|
poolname) == 0);
|
||||||
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE,
|
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE,
|
||||||
state) == 0);
|
state) == 0);
|
||||||
|
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TIMESTAMP,
|
||||||
|
spa->spa_uberblock.ub_timestamp) == 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add the list of hot spares.
|
* Add the list of hot spares.
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <sys/fs/zfs.h>
|
#include <sys/fs/zfs.h>
|
||||||
#include <sys/vdev_impl.h>
|
#include <sys/vdev_impl.h>
|
||||||
#include <sys/zfs_ioctl.h>
|
#include <sys/zfs_ioctl.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
#include <sys/kobj.h>
|
#include <sys/kobj.h>
|
||||||
#endif
|
#endif
|
||||||
@ -268,6 +269,7 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
|
|||||||
{
|
{
|
||||||
nvlist_t *config, *nvroot;
|
nvlist_t *config, *nvroot;
|
||||||
vdev_t *rvd = spa->spa_root_vdev;
|
vdev_t *rvd = spa->spa_root_vdev;
|
||||||
|
unsigned long hostid = 0;
|
||||||
|
|
||||||
ASSERT(spa_config_held(spa, RW_READER));
|
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);
|
txg) == 0);
|
||||||
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
||||||
spa_guid(spa)) == 0);
|
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) {
|
if (vd != rvd) {
|
||||||
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID,
|
VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID,
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
* CDDL HEADER END
|
* 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.
|
* 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,
|
int dsl_dir_open_obj(dsl_pool_t *dp, uint64_t ddobj,
|
||||||
const char *tail, void *tag, dsl_dir_t **);
|
const char *tail, void *tag, dsl_dir_t **);
|
||||||
void dsl_dir_name(dsl_dir_t *dd, char *buf);
|
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);
|
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);
|
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);
|
void dsl_dir_create_root(objset_t *mos, uint64_t *ddobjp, dmu_tx_t *tx);
|
||||||
|
@ -46,7 +46,6 @@ extern "C" {
|
|||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <sys/taskq.h>
|
#include <sys/taskq.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/kobj.h>
|
|
||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
#include <sys/rwlock.h>
|
#include <sys/rwlock.h>
|
||||||
@ -77,6 +76,7 @@ extern "C" {
|
|||||||
#include <sys/policy.h>
|
#include <sys/policy.h>
|
||||||
#include <sys/zone.h>
|
#include <sys/zone.h>
|
||||||
#include <sys/eventhandler.h>
|
#include <sys/eventhandler.h>
|
||||||
|
#include <sys/misc.h>
|
||||||
#include <sys/zfs_debug.h>
|
#include <sys/zfs_debug.h>
|
||||||
|
|
||||||
#include <machine/stdarg.h>
|
#include <machine/stdarg.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_SPARES "spares"
|
||||||
#define ZPOOL_CONFIG_IS_SPARE "is_spare"
|
#define ZPOOL_CONFIG_IS_SPARE "is_spare"
|
||||||
#define ZPOOL_CONFIG_NPARITY "nparity"
|
#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_ROOT "root"
|
||||||
#define VDEV_TYPE_MIRROR "mirror"
|
#define VDEV_TYPE_MIRROR "mirror"
|
||||||
|
@ -15,6 +15,7 @@ SRCS+= nvpair.c
|
|||||||
SRCS+= opensolaris_kmem.c
|
SRCS+= opensolaris_kmem.c
|
||||||
SRCS+= opensolaris_kobj.c
|
SRCS+= opensolaris_kobj.c
|
||||||
SRCS+= opensolaris_kstat.c
|
SRCS+= opensolaris_kstat.c
|
||||||
|
SRCS+= opensolaris_misc.c
|
||||||
SRCS+= opensolaris_policy.c
|
SRCS+= opensolaris_policy.c
|
||||||
SRCS+= opensolaris_string.c
|
SRCS+= opensolaris_string.c
|
||||||
SRCS+= opensolaris_vfs.c
|
SRCS+= opensolaris_vfs.c
|
||||||
|
Loading…
Reference in New Issue
Block a user