mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
Update to onnv_147
This is the last official OpenSolaris tag before the public development tree was closed.
This commit is contained in:
+18
-11
@@ -695,12 +695,12 @@ dump_ddt(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
|
||||
return;
|
||||
ASSERT(error == 0);
|
||||
|
||||
count = ddt_object_count(ddt, type, class);
|
||||
if ((count = ddt_object_count(ddt, type, class)) == 0)
|
||||
return;
|
||||
|
||||
dspace = doi.doi_physical_blocks_512 << 9;
|
||||
mspace = doi.doi_fill_count * doi.doi_data_block_size;
|
||||
|
||||
ASSERT(count != 0); /* we should have destroyed it */
|
||||
|
||||
ddt_object_name(ddt, type, class, name);
|
||||
|
||||
(void) printf("%s: %llu entries, size %llu on disk, %llu in core\n",
|
||||
@@ -1290,8 +1290,12 @@ dump_znode(objset_t *os, uint64_t object, void *data, size_t size)
|
||||
VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS,
|
||||
8, 1, &sa_attrs) == 0);
|
||||
}
|
||||
sa_attr_table = sa_setup(os, sa_attrs,
|
||||
zfs_attr_table, ZPL_END);
|
||||
if ((error = sa_setup(os, sa_attrs, zfs_attr_table,
|
||||
ZPL_END, &sa_attr_table)) != 0) {
|
||||
(void) printf("sa_setup failed errno %d, can't "
|
||||
"display znode contents\n", error);
|
||||
return;
|
||||
}
|
||||
sa_loaded = B_TRUE;
|
||||
}
|
||||
|
||||
@@ -1455,7 +1459,7 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header)
|
||||
}
|
||||
|
||||
if (object == 0) {
|
||||
dn = os->os_meta_dnode;
|
||||
dn = DMU_META_DNODE(os);
|
||||
} else {
|
||||
error = dmu_bonus_hold(os, object, FTAG, &db);
|
||||
if (error)
|
||||
@@ -1463,7 +1467,7 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header)
|
||||
object, error);
|
||||
bonus = db->db_data;
|
||||
bsize = db->db_size;
|
||||
dn = ((dmu_buf_impl_t *)db)->db_dnode;
|
||||
dn = DB_DNODE((dmu_buf_impl_t *)db);
|
||||
}
|
||||
dmu_object_info_from_dnode(dn, &doi);
|
||||
|
||||
@@ -1627,8 +1631,8 @@ dump_dir(objset_t *os)
|
||||
|
||||
dump_object(os, 0, verbosity, &print_header);
|
||||
object_count = 0;
|
||||
if (os->os_userused_dnode &&
|
||||
os->os_userused_dnode->dn_type != 0) {
|
||||
if (DMU_USERUSED_DNODE(os) != NULL &&
|
||||
DMU_USERUSED_DNODE(os)->dn_type != 0) {
|
||||
dump_object(os, DMU_USERUSED_OBJECT, verbosity, &print_header);
|
||||
dump_object(os, DMU_GROUPUSED_OBJECT, verbosity, &print_header);
|
||||
}
|
||||
@@ -3072,8 +3076,11 @@ main(int argc, char **argv)
|
||||
fatal("can't open '%s': %s",
|
||||
target, strerror(ENOMEM));
|
||||
}
|
||||
if ((error = spa_import(name, cfg, NULL)) != 0)
|
||||
error = spa_import_verbatim(name, cfg, NULL);
|
||||
if ((error = spa_import(name, cfg, NULL,
|
||||
ZFS_IMPORT_MISSING_LOG)) != 0) {
|
||||
error = spa_import(name, cfg, NULL,
|
||||
ZFS_IMPORT_VERBATIM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+323
-314
@@ -40,6 +40,7 @@
|
||||
#include <zone.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/mkdev.h>
|
||||
#include <sys/mntent.h>
|
||||
#include <sys/mnttab.h>
|
||||
@@ -84,6 +85,7 @@ static int zfs_do_userspace(int argc, char **argv);
|
||||
static int zfs_do_python(int argc, char **argv);
|
||||
static int zfs_do_hold(int argc, char **argv);
|
||||
static int zfs_do_release(int argc, char **argv);
|
||||
static int zfs_do_diff(int argc, char **argv);
|
||||
|
||||
/*
|
||||
* Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
|
||||
@@ -128,7 +130,8 @@ typedef enum {
|
||||
HELP_GROUPSPACE,
|
||||
HELP_HOLD,
|
||||
HELP_HOLDS,
|
||||
HELP_RELEASE
|
||||
HELP_RELEASE,
|
||||
HELP_DIFF
|
||||
} zfs_help_t;
|
||||
|
||||
typedef struct zfs_command {
|
||||
@@ -180,6 +183,7 @@ static zfs_command_t command_table[] = {
|
||||
{ "hold", zfs_do_hold, HELP_HOLD },
|
||||
{ "holds", zfs_do_python, HELP_HOLDS },
|
||||
{ "release", zfs_do_release, HELP_RELEASE },
|
||||
{ "diff", zfs_do_diff, HELP_DIFF },
|
||||
};
|
||||
|
||||
#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
|
||||
@@ -283,6 +287,9 @@ get_usage(zfs_help_t idx)
|
||||
return (gettext("\tholds [-r] <snapshot> ...\n"));
|
||||
case HELP_RELEASE:
|
||||
return (gettext("\trelease [-r] <tag> <snapshot> ...\n"));
|
||||
case HELP_DIFF:
|
||||
return (gettext("\tdiff [-FHt] <snapshot> "
|
||||
"[snapshot|filesystem]\n"));
|
||||
}
|
||||
|
||||
abort();
|
||||
@@ -624,8 +631,9 @@ zfs_do_clone(int argc, char **argv)
|
||||
|
||||
clone = zfs_open(g_zfs, argv[1], ZFS_TYPE_DATASET);
|
||||
if (clone != NULL) {
|
||||
if ((ret = zfs_mount(clone, NULL, 0)) == 0)
|
||||
ret = zfs_share(clone);
|
||||
if (zfs_get_type(clone) != ZFS_TYPE_VOLUME)
|
||||
if ((ret = zfs_mount(clone, NULL, 0)) == 0)
|
||||
ret = zfs_share(clone);
|
||||
zfs_close(clone);
|
||||
}
|
||||
}
|
||||
@@ -671,7 +679,7 @@ zfs_do_create(int argc, char **argv)
|
||||
int ret = 1;
|
||||
nvlist_t *props;
|
||||
uint64_t intval;
|
||||
int canmount;
|
||||
int canmount = ZFS_CANMOUNT_OFF;
|
||||
|
||||
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
|
||||
nomem();
|
||||
@@ -802,19 +810,20 @@ zfs_do_create(int argc, char **argv)
|
||||
|
||||
if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL)
|
||||
goto error;
|
||||
|
||||
ret = 0;
|
||||
/*
|
||||
* if the user doesn't want the dataset automatically mounted,
|
||||
* then skip the mount/share step
|
||||
*/
|
||||
|
||||
canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
|
||||
if (zfs_prop_valid_for_type(ZFS_PROP_CANMOUNT, type))
|
||||
canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
|
||||
|
||||
/*
|
||||
* Mount and/or share the new filesystem as appropriate. We provide a
|
||||
* verbose error message to let the user know that their filesystem was
|
||||
* in fact created, even if we failed to mount or share it.
|
||||
*/
|
||||
ret = 0;
|
||||
if (canmount == ZFS_CANMOUNT_ON) {
|
||||
if (zfs_mount(zhp, NULL, 0) != 0) {
|
||||
(void) fprintf(stderr, gettext("filesystem "
|
||||
@@ -2888,7 +2897,7 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
|
||||
}
|
||||
if (holding) {
|
||||
if (zfs_hold(zhp, delim+1, tag, recursive,
|
||||
temphold, B_FALSE) != 0)
|
||||
temphold, B_FALSE, -1, 0, 0) != 0)
|
||||
++errors;
|
||||
} else {
|
||||
if (zfs_release(zhp, delim+1, tag, recursive) != 0)
|
||||
@@ -2927,14 +2936,6 @@ zfs_do_release(int argc, char **argv)
|
||||
return (zfs_do_hold_rele_impl(argc, argv, B_FALSE));
|
||||
}
|
||||
|
||||
typedef struct get_all_cbdata {
|
||||
zfs_handle_t **cb_handles;
|
||||
size_t cb_alloc;
|
||||
size_t cb_used;
|
||||
uint_t cb_types;
|
||||
boolean_t cb_verbose;
|
||||
} get_all_cbdata_t;
|
||||
|
||||
#define CHECK_SPINNER 30
|
||||
#define SPINNER_TIME 3 /* seconds */
|
||||
#define MOUNT_TIME 5 /* seconds */
|
||||
@@ -2946,7 +2947,7 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
|
||||
static int spinval = 0;
|
||||
static int spincheck = 0;
|
||||
static time_t last_spin_time = (time_t)0;
|
||||
get_all_cbdata_t *cbp = data;
|
||||
get_all_cb_t *cbp = data;
|
||||
zfs_type_t type = zfs_get_type(zhp);
|
||||
|
||||
if (cbp->cb_verbose) {
|
||||
@@ -2963,8 +2964,7 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
|
||||
/*
|
||||
* Interate over any nested datasets.
|
||||
*/
|
||||
if (type == ZFS_TYPE_FILESYSTEM &&
|
||||
zfs_iter_filesystems(zhp, get_one_dataset, data) != 0) {
|
||||
if (zfs_iter_filesystems(zhp, get_one_dataset, data) != 0) {
|
||||
zfs_close(zhp);
|
||||
return (1);
|
||||
}
|
||||
@@ -2972,46 +2972,25 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
|
||||
/*
|
||||
* Skip any datasets whose type does not match.
|
||||
*/
|
||||
if ((type & cbp->cb_types) == 0) {
|
||||
if ((type & ZFS_TYPE_FILESYSTEM) == 0) {
|
||||
zfs_close(zhp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (cbp->cb_alloc == cbp->cb_used) {
|
||||
zfs_handle_t **handles;
|
||||
|
||||
if (cbp->cb_alloc == 0)
|
||||
cbp->cb_alloc = 64;
|
||||
else
|
||||
cbp->cb_alloc *= 2;
|
||||
|
||||
handles = safe_malloc(cbp->cb_alloc * sizeof (void *));
|
||||
|
||||
if (cbp->cb_handles) {
|
||||
bcopy(cbp->cb_handles, handles,
|
||||
cbp->cb_used * sizeof (void *));
|
||||
free(cbp->cb_handles);
|
||||
}
|
||||
|
||||
cbp->cb_handles = handles;
|
||||
}
|
||||
|
||||
cbp->cb_handles[cbp->cb_used++] = zhp;
|
||||
libzfs_add_handle(cbp, zhp);
|
||||
assert(cbp->cb_used <= cbp->cb_alloc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
get_all_datasets(uint_t types, zfs_handle_t ***dslist, size_t *count,
|
||||
boolean_t verbose)
|
||||
get_all_datasets(zfs_handle_t ***dslist, size_t *count, boolean_t verbose)
|
||||
{
|
||||
get_all_cbdata_t cb = { 0 };
|
||||
cb.cb_types = types;
|
||||
get_all_cb_t cb = { 0 };
|
||||
cb.cb_verbose = verbose;
|
||||
cb.cb_getone = get_one_dataset;
|
||||
|
||||
if (verbose)
|
||||
set_progress_header(gettext("Reading ZFS config"));
|
||||
|
||||
(void) zfs_iter_root(g_zfs, get_one_dataset, &cb);
|
||||
|
||||
*dslist = cb.cb_handles;
|
||||
@@ -3021,33 +3000,6 @@ get_all_datasets(uint_t types, zfs_handle_t ***dslist, size_t *count,
|
||||
finish_progress(gettext("done."));
|
||||
}
|
||||
|
||||
static int
|
||||
dataset_cmp(const void *a, const void *b)
|
||||
{
|
||||
zfs_handle_t **za = (zfs_handle_t **)a;
|
||||
zfs_handle_t **zb = (zfs_handle_t **)b;
|
||||
char mounta[MAXPATHLEN];
|
||||
char mountb[MAXPATHLEN];
|
||||
boolean_t gota, gotb;
|
||||
|
||||
if ((gota = (zfs_get_type(*za) == ZFS_TYPE_FILESYSTEM)) != 0)
|
||||
verify(zfs_prop_get(*za, ZFS_PROP_MOUNTPOINT, mounta,
|
||||
sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
|
||||
if ((gotb = (zfs_get_type(*zb) == ZFS_TYPE_FILESYSTEM)) != 0)
|
||||
verify(zfs_prop_get(*zb, ZFS_PROP_MOUNTPOINT, mountb,
|
||||
sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
|
||||
|
||||
if (gota && gotb)
|
||||
return (strcmp(mounta, mountb));
|
||||
|
||||
if (gota)
|
||||
return (-1);
|
||||
if (gotb)
|
||||
return (1);
|
||||
|
||||
return (strcmp(zfs_get_name(a), zfs_get_name(b)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic callback for sharing or mounting filesystems. Because the code is so
|
||||
* similar, we have a common function with an extra parameter to determine which
|
||||
@@ -3069,184 +3021,180 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
|
||||
const char *cmdname = op == OP_SHARE ? "share" : "mount";
|
||||
struct mnttab mnt;
|
||||
uint64_t zoned, canmount;
|
||||
zfs_type_t type = zfs_get_type(zhp);
|
||||
boolean_t shared_nfs, shared_smb;
|
||||
|
||||
assert(type & (ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME));
|
||||
assert(zfs_get_type(zhp) & ZFS_TYPE_FILESYSTEM);
|
||||
|
||||
if (type == ZFS_TYPE_FILESYSTEM) {
|
||||
/*
|
||||
* Check to make sure we can mount/share this dataset. If we
|
||||
* are in the global zone and the filesystem is exported to a
|
||||
* local zone, or if we are in a local zone and the
|
||||
* filesystem is not exported, then it is an error.
|
||||
*/
|
||||
zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
|
||||
/*
|
||||
* Check to make sure we can mount/share this dataset. If we
|
||||
* are in the global zone and the filesystem is exported to a
|
||||
* local zone, or if we are in a local zone and the
|
||||
* filesystem is not exported, then it is an error.
|
||||
*/
|
||||
zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
|
||||
|
||||
if (zoned && getzoneid() == GLOBAL_ZONEID) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
||||
"dataset is exported to a local zone\n"), cmdname,
|
||||
zfs_get_name(zhp));
|
||||
return (1);
|
||||
|
||||
} else if (!zoned && getzoneid() != GLOBAL_ZONEID) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
||||
"permission denied\n"), cmdname,
|
||||
zfs_get_name(zhp));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore any filesystems which don't apply to us. This
|
||||
* includes those with a legacy mountpoint, or those with
|
||||
* legacy share options.
|
||||
*/
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
|
||||
sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0);
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts,
|
||||
sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0);
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, smbshareopts,
|
||||
sizeof (smbshareopts), NULL, NULL, 0, B_FALSE) == 0);
|
||||
|
||||
if (op == OP_SHARE && strcmp(shareopts, "off") == 0 &&
|
||||
strcmp(smbshareopts, "off") == 0) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot share '%s': "
|
||||
"legacy share\n"), zfs_get_name(zhp));
|
||||
(void) fprintf(stderr, gettext("use share(1M) to "
|
||||
"share this filesystem, or set "
|
||||
"sharenfs property on\n"));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot share or mount legacy filesystems. If the
|
||||
* shareopts is non-legacy but the mountpoint is legacy, we
|
||||
* treat it as a legacy share.
|
||||
*/
|
||||
if (strcmp(mountpoint, "legacy") == 0) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
||||
"legacy mountpoint\n"), cmdname, zfs_get_name(zhp));
|
||||
(void) fprintf(stderr, gettext("use %s(1M) to "
|
||||
"%s this filesystem\n"), cmdname, cmdname);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (strcmp(mountpoint, "none") == 0) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': no "
|
||||
"mountpoint set\n"), cmdname, zfs_get_name(zhp));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* canmount explicit outcome
|
||||
* on no pass through
|
||||
* on yes pass through
|
||||
* off no return 0
|
||||
* off yes display error, return 1
|
||||
* noauto no return 0
|
||||
* noauto yes pass through
|
||||
*/
|
||||
canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
|
||||
if (canmount == ZFS_CANMOUNT_OFF) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
||||
"'canmount' property is set to 'off'\n"), cmdname,
|
||||
zfs_get_name(zhp));
|
||||
return (1);
|
||||
} else if (canmount == ZFS_CANMOUNT_NOAUTO && !explicit) {
|
||||
if (zoned && getzoneid() == GLOBAL_ZONEID) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
||||
"dataset is exported to a local zone\n"), cmdname,
|
||||
zfs_get_name(zhp));
|
||||
return (1);
|
||||
|
||||
} else if (!zoned && getzoneid() != GLOBAL_ZONEID) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
||||
"permission denied\n"), cmdname,
|
||||
zfs_get_name(zhp));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore any filesystems which don't apply to us. This
|
||||
* includes those with a legacy mountpoint, or those with
|
||||
* legacy share options.
|
||||
*/
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
|
||||
sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0);
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts,
|
||||
sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0);
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, smbshareopts,
|
||||
sizeof (smbshareopts), NULL, NULL, 0, B_FALSE) == 0);
|
||||
|
||||
if (op == OP_SHARE && strcmp(shareopts, "off") == 0 &&
|
||||
strcmp(smbshareopts, "off") == 0) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot share '%s': "
|
||||
"legacy share\n"), zfs_get_name(zhp));
|
||||
(void) fprintf(stderr, gettext("use share(1M) to "
|
||||
"share this filesystem, or set "
|
||||
"sharenfs property on\n"));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot share or mount legacy filesystems. If the
|
||||
* shareopts is non-legacy but the mountpoint is legacy, we
|
||||
* treat it as a legacy share.
|
||||
*/
|
||||
if (strcmp(mountpoint, "legacy") == 0) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
||||
"legacy mountpoint\n"), cmdname, zfs_get_name(zhp));
|
||||
(void) fprintf(stderr, gettext("use %s(1M) to "
|
||||
"%s this filesystem\n"), cmdname, cmdname);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (strcmp(mountpoint, "none") == 0) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': no "
|
||||
"mountpoint set\n"), cmdname, zfs_get_name(zhp));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* canmount explicit outcome
|
||||
* on no pass through
|
||||
* on yes pass through
|
||||
* off no return 0
|
||||
* off yes display error, return 1
|
||||
* noauto no return 0
|
||||
* noauto yes pass through
|
||||
*/
|
||||
canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
|
||||
if (canmount == ZFS_CANMOUNT_OFF) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot %s '%s': "
|
||||
"'canmount' property is set to 'off'\n"), cmdname,
|
||||
zfs_get_name(zhp));
|
||||
return (1);
|
||||
} else if (canmount == ZFS_CANMOUNT_NOAUTO && !explicit) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we have verified that the mountpoint and/or
|
||||
* shareopts are appropriate for auto management. If the
|
||||
* filesystem is already mounted or shared, return (failing
|
||||
* for explicit requests); otherwise mount or share the
|
||||
* filesystem.
|
||||
*/
|
||||
switch (op) {
|
||||
case OP_SHARE:
|
||||
|
||||
shared_nfs = zfs_is_shared_nfs(zhp, NULL);
|
||||
shared_smb = zfs_is_shared_smb(zhp, NULL);
|
||||
|
||||
if (shared_nfs && shared_smb ||
|
||||
(shared_nfs && strcmp(shareopts, "on") == 0 &&
|
||||
strcmp(smbshareopts, "off") == 0) ||
|
||||
(shared_smb && strcmp(smbshareopts, "on") == 0 &&
|
||||
strcmp(shareopts, "off") == 0)) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot share "
|
||||
"'%s': filesystem already shared\n"),
|
||||
zfs_get_name(zhp));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we have verified that the mountpoint and/or
|
||||
* shareopts are appropriate for auto management. If the
|
||||
* filesystem is already mounted or shared, return (failing
|
||||
* for explicit requests); otherwise mount or share the
|
||||
* filesystem.
|
||||
*/
|
||||
switch (op) {
|
||||
case OP_SHARE:
|
||||
if (!zfs_is_mounted(zhp, NULL) &&
|
||||
zfs_mount(zhp, NULL, 0) != 0)
|
||||
return (1);
|
||||
|
||||
shared_nfs = zfs_is_shared_nfs(zhp, NULL);
|
||||
shared_smb = zfs_is_shared_smb(zhp, NULL);
|
||||
|
||||
if (shared_nfs && shared_smb ||
|
||||
(shared_nfs && strcmp(shareopts, "on") == 0 &&
|
||||
strcmp(smbshareopts, "off") == 0) ||
|
||||
(shared_smb && strcmp(smbshareopts, "on") == 0 &&
|
||||
strcmp(shareopts, "off") == 0)) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot share "
|
||||
"'%s': filesystem already shared\n"),
|
||||
zfs_get_name(zhp));
|
||||
if (protocol == NULL) {
|
||||
if (zfs_shareall(zhp) != 0)
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!zfs_is_mounted(zhp, NULL) &&
|
||||
zfs_mount(zhp, NULL, 0) != 0)
|
||||
} else if (strcmp(protocol, "nfs") == 0) {
|
||||
if (zfs_share_nfs(zhp))
|
||||
return (1);
|
||||
|
||||
if (protocol == NULL) {
|
||||
if (zfs_shareall(zhp) != 0)
|
||||
return (1);
|
||||
} else if (strcmp(protocol, "nfs") == 0) {
|
||||
if (zfs_share_nfs(zhp))
|
||||
return (1);
|
||||
} else if (strcmp(protocol, "smb") == 0) {
|
||||
if (zfs_share_smb(zhp))
|
||||
return (1);
|
||||
} else {
|
||||
(void) fprintf(stderr, gettext("cannot share "
|
||||
"'%s': invalid share type '%s' "
|
||||
"specified\n"),
|
||||
zfs_get_name(zhp), protocol);
|
||||
} else if (strcmp(protocol, "smb") == 0) {
|
||||
if (zfs_share_smb(zhp))
|
||||
return (1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case OP_MOUNT:
|
||||
if (options == NULL)
|
||||
mnt.mnt_mntopts = "";
|
||||
else
|
||||
mnt.mnt_mntopts = (char *)options;
|
||||
|
||||
if (!hasmntopt(&mnt, MNTOPT_REMOUNT) &&
|
||||
zfs_is_mounted(zhp, NULL)) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot mount "
|
||||
"'%s': filesystem already mounted\n"),
|
||||
zfs_get_name(zhp));
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (zfs_mount(zhp, options, flags) != 0)
|
||||
return (1);
|
||||
break;
|
||||
} else {
|
||||
(void) fprintf(stderr, gettext("cannot share "
|
||||
"'%s': invalid share type '%s' "
|
||||
"specified\n"),
|
||||
zfs_get_name(zhp), protocol);
|
||||
return (1);
|
||||
}
|
||||
} else
|
||||
assert(op == OP_SHARE);
|
||||
|
||||
break;
|
||||
|
||||
case OP_MOUNT:
|
||||
if (options == NULL)
|
||||
mnt.mnt_mntopts = "";
|
||||
else
|
||||
mnt.mnt_mntopts = (char *)options;
|
||||
|
||||
if (!hasmntopt(&mnt, MNTOPT_REMOUNT) &&
|
||||
zfs_is_mounted(zhp, NULL)) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
(void) fprintf(stderr, gettext("cannot mount "
|
||||
"'%s': filesystem already mounted\n"),
|
||||
zfs_get_name(zhp));
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (zfs_mount(zhp, options, flags) != 0)
|
||||
return (1);
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -3308,7 +3256,7 @@ share_mount(int op, int argc, char **argv)
|
||||
boolean_t verbose = B_FALSE;
|
||||
int c, ret = 0;
|
||||
char *options = NULL;
|
||||
int types, flags = 0;
|
||||
int flags = 0;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, op == OP_MOUNT ? ":avo:O" : "a"))
|
||||
@@ -3358,13 +3306,9 @@ share_mount(int op, int argc, char **argv)
|
||||
size_t i, count = 0;
|
||||
char *protocol = NULL;
|
||||
|
||||
if (op == OP_MOUNT) {
|
||||
types = ZFS_TYPE_FILESYSTEM;
|
||||
} else if (argc > 0) {
|
||||
if (strcmp(argv[0], "nfs") == 0 ||
|
||||
strcmp(argv[0], "smb") == 0) {
|
||||
types = ZFS_TYPE_FILESYSTEM;
|
||||
} else {
|
||||
if (op == OP_SHARE && argc > 0) {
|
||||
if (strcmp(argv[0], "nfs") != 0 &&
|
||||
strcmp(argv[0], "smb") != 0) {
|
||||
(void) fprintf(stderr, gettext("share type "
|
||||
"must be 'nfs' or 'smb'\n"));
|
||||
usage(B_FALSE);
|
||||
@@ -3372,8 +3316,6 @@ share_mount(int op, int argc, char **argv)
|
||||
protocol = argv[0];
|
||||
argc--;
|
||||
argv++;
|
||||
} else {
|
||||
types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
|
||||
}
|
||||
|
||||
if (argc != 0) {
|
||||
@@ -3382,12 +3324,12 @@ share_mount(int op, int argc, char **argv)
|
||||
}
|
||||
|
||||
start_progress_timer();
|
||||
get_all_datasets(types, &dslist, &count, verbose);
|
||||
get_all_datasets(&dslist, &count, verbose);
|
||||
|
||||
if (count == 0)
|
||||
return (0);
|
||||
|
||||
qsort(dslist, count, sizeof (void *), dataset_cmp);
|
||||
qsort(dslist, count, sizeof (void *), libzfs_dataset_cmp);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (verbose)
|
||||
@@ -3427,17 +3369,14 @@ share_mount(int op, int argc, char **argv)
|
||||
} else {
|
||||
zfs_handle_t *zhp;
|
||||
|
||||
types = ZFS_TYPE_FILESYSTEM;
|
||||
if (op == OP_SHARE)
|
||||
types |= ZFS_TYPE_VOLUME;
|
||||
|
||||
if (argc > 1) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("too many arguments\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if ((zhp = zfs_open(g_zfs, argv[0], types)) == NULL) {
|
||||
if ((zhp = zfs_open(g_zfs, argv[0],
|
||||
ZFS_TYPE_FILESYSTEM)) == NULL) {
|
||||
ret = 1;
|
||||
} else {
|
||||
ret = share_mount_one(zhp, op, flags, NULL, B_TRUE,
|
||||
@@ -3616,7 +3555,7 @@ unshare_unmount(int op, int argc, char **argv)
|
||||
int do_all = 0;
|
||||
int flags = 0;
|
||||
int ret = 0;
|
||||
int types, c;
|
||||
int c;
|
||||
zfs_handle_t *zhp;
|
||||
char nfs_mnt_prop[ZFS_MAXPROPLEN];
|
||||
char sharesmb[ZFS_MAXPROPLEN];
|
||||
@@ -3792,68 +3731,63 @@ unshare_unmount(int op, int argc, char **argv)
|
||||
return (unshare_unmount_path(op, argv[0],
|
||||
flags, B_FALSE));
|
||||
|
||||
types = ZFS_TYPE_FILESYSTEM;
|
||||
if (op == OP_SHARE)
|
||||
types |= ZFS_TYPE_VOLUME;
|
||||
|
||||
if ((zhp = zfs_open(g_zfs, argv[0], types)) == NULL)
|
||||
if ((zhp = zfs_open(g_zfs, argv[0],
|
||||
ZFS_TYPE_FILESYSTEM)) == NULL)
|
||||
return (1);
|
||||
|
||||
if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
|
||||
verify(zfs_prop_get(zhp, op == OP_SHARE ?
|
||||
ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT,
|
||||
nfs_mnt_prop, sizeof (nfs_mnt_prop), NULL,
|
||||
NULL, 0, B_FALSE) == 0);
|
||||
verify(zfs_prop_get(zhp, op == OP_SHARE ?
|
||||
ZFS_PROP_SHARENFS : ZFS_PROP_MOUNTPOINT,
|
||||
nfs_mnt_prop, sizeof (nfs_mnt_prop), NULL,
|
||||
NULL, 0, B_FALSE) == 0);
|
||||
|
||||
switch (op) {
|
||||
case OP_SHARE:
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS,
|
||||
nfs_mnt_prop,
|
||||
sizeof (nfs_mnt_prop),
|
||||
NULL, NULL, 0, B_FALSE) == 0);
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB,
|
||||
sharesmb, sizeof (sharesmb), NULL, NULL,
|
||||
0, B_FALSE) == 0);
|
||||
switch (op) {
|
||||
case OP_SHARE:
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS,
|
||||
nfs_mnt_prop,
|
||||
sizeof (nfs_mnt_prop),
|
||||
NULL, NULL, 0, B_FALSE) == 0);
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB,
|
||||
sharesmb, sizeof (sharesmb), NULL, NULL,
|
||||
0, B_FALSE) == 0);
|
||||
|
||||
if (strcmp(nfs_mnt_prop, "off") == 0 &&
|
||||
strcmp(sharesmb, "off") == 0) {
|
||||
(void) fprintf(stderr, gettext("cannot "
|
||||
"unshare '%s': legacy share\n"),
|
||||
zfs_get_name(zhp));
|
||||
(void) fprintf(stderr, gettext("use "
|
||||
"unshare(1M) to unshare this "
|
||||
"filesystem\n"));
|
||||
ret = 1;
|
||||
} else if (!zfs_is_shared(zhp)) {
|
||||
(void) fprintf(stderr, gettext("cannot "
|
||||
"unshare '%s': not currently "
|
||||
"shared\n"), zfs_get_name(zhp));
|
||||
ret = 1;
|
||||
} else if (zfs_unshareall(zhp) != 0) {
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_MOUNT:
|
||||
if (strcmp(nfs_mnt_prop, "legacy") == 0) {
|
||||
(void) fprintf(stderr, gettext("cannot "
|
||||
"unmount '%s': legacy "
|
||||
"mountpoint\n"), zfs_get_name(zhp));
|
||||
(void) fprintf(stderr, gettext("use "
|
||||
"umount(1M) to unmount this "
|
||||
"filesystem\n"));
|
||||
ret = 1;
|
||||
} else if (!zfs_is_mounted(zhp, NULL)) {
|
||||
(void) fprintf(stderr, gettext("cannot "
|
||||
"unmount '%s': not currently "
|
||||
"mounted\n"),
|
||||
zfs_get_name(zhp));
|
||||
ret = 1;
|
||||
} else if (zfs_unmountall(zhp, flags) != 0) {
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
if (strcmp(nfs_mnt_prop, "off") == 0 &&
|
||||
strcmp(sharesmb, "off") == 0) {
|
||||
(void) fprintf(stderr, gettext("cannot "
|
||||
"unshare '%s': legacy share\n"),
|
||||
zfs_get_name(zhp));
|
||||
(void) fprintf(stderr, gettext("use "
|
||||
"unshare(1M) to unshare this "
|
||||
"filesystem\n"));
|
||||
ret = 1;
|
||||
} else if (!zfs_is_shared(zhp)) {
|
||||
(void) fprintf(stderr, gettext("cannot "
|
||||
"unshare '%s': not currently "
|
||||
"shared\n"), zfs_get_name(zhp));
|
||||
ret = 1;
|
||||
} else if (zfs_unshareall(zhp) != 0) {
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_MOUNT:
|
||||
if (strcmp(nfs_mnt_prop, "legacy") == 0) {
|
||||
(void) fprintf(stderr, gettext("cannot "
|
||||
"unmount '%s': legacy "
|
||||
"mountpoint\n"), zfs_get_name(zhp));
|
||||
(void) fprintf(stderr, gettext("use "
|
||||
"umount(1M) to unmount this "
|
||||
"filesystem\n"));
|
||||
ret = 1;
|
||||
} else if (!zfs_is_mounted(zhp, NULL)) {
|
||||
(void) fprintf(stderr, gettext("cannot "
|
||||
"unmount '%s': not currently "
|
||||
"mounted\n"),
|
||||
zfs_get_name(zhp));
|
||||
ret = 1;
|
||||
} else if (zfs_unmountall(zhp, flags) != 0) {
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
zfs_close(zhp);
|
||||
@@ -4047,6 +3981,81 @@ find_command_idx(char *command, int *idx)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_do_diff(int argc, char **argv)
|
||||
{
|
||||
zfs_handle_t *zhp;
|
||||
int flags = 0;
|
||||
char *tosnap = NULL;
|
||||
char *fromsnap = NULL;
|
||||
char *atp, *copy;
|
||||
int err;
|
||||
int c;
|
||||
|
||||
while ((c = getopt(argc, argv, "FHt")) != -1) {
|
||||
switch (c) {
|
||||
case 'F':
|
||||
flags |= ZFS_DIFF_CLASSIFY;
|
||||
break;
|
||||
case 'H':
|
||||
flags |= ZFS_DIFF_PARSEABLE;
|
||||
break;
|
||||
case 't':
|
||||
flags |= ZFS_DIFF_TIMESTAMP;
|
||||
break;
|
||||
default:
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid option '%c'\n"), optopt);
|
||||
usage(B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("must provide at least one snapshot name\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
fromsnap = argv[0];
|
||||
tosnap = (argc == 2) ? argv[1] : NULL;
|
||||
|
||||
copy = NULL;
|
||||
if (*fromsnap != '@')
|
||||
copy = strdup(fromsnap);
|
||||
else if (tosnap)
|
||||
copy = strdup(tosnap);
|
||||
if (copy == NULL)
|
||||
usage(B_FALSE);
|
||||
|
||||
if (atp = strchr(copy, '@'))
|
||||
*atp = '\0';
|
||||
|
||||
if ((zhp = zfs_open(g_zfs, copy, ZFS_TYPE_FILESYSTEM)) == NULL)
|
||||
return (1);
|
||||
|
||||
free(copy);
|
||||
|
||||
/*
|
||||
* Ignore SIGPIPE so that the library can give us
|
||||
* information on any failure
|
||||
*/
|
||||
(void) sigignore(SIGPIPE);
|
||||
|
||||
err = zfs_show_diffs(zhp, STDOUT_FILENO, fromsnap, tosnap, flags);
|
||||
|
||||
zfs_close(zhp);
|
||||
|
||||
return (err != 0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
||||
@@ -267,7 +267,7 @@ calculate_range(const char *dataset, err_type_t type, int level, char *range,
|
||||
}
|
||||
|
||||
if (record->zi_object == 0) {
|
||||
dn = os->os_meta_dnode;
|
||||
dn = DMU_META_DNODE(os);
|
||||
} else {
|
||||
err = dnode_hold(os, record->zi_object, FTAG, &dn);
|
||||
if (err != 0) {
|
||||
@@ -318,7 +318,7 @@ calculate_range(const char *dataset, err_type_t type, int level, char *range,
|
||||
ret = 0;
|
||||
out:
|
||||
if (dn) {
|
||||
if (dn != os->os_meta_dnode)
|
||||
if (dn != DMU_META_DNODE(os))
|
||||
dnode_rele(dn, FTAG);
|
||||
}
|
||||
if (os)
|
||||
|
||||
+17
-7
@@ -233,7 +233,7 @@ usage(void)
|
||||
"\t\tInject a fault into a particular device or the device's\n"
|
||||
"\t\tlabel. Label injection can either be 'nvlist', 'uber',\n "
|
||||
"\t\t'pad1', or 'pad2'.\n"
|
||||
"\t\t'errno' can either be 'nxio' (the default) or 'io'.\n"
|
||||
"\t\t'errno' can be 'nxio' (the default), 'io', or 'dtl'.\n"
|
||||
"\n"
|
||||
"\tzinject -d device -A <degrade|fault> pool\n"
|
||||
"\t\tPerform a specific action on a particular device\n"
|
||||
@@ -395,17 +395,25 @@ print_panic_handler(int id, const char *pool, zinject_record_t *record,
|
||||
static int
|
||||
print_all_handlers(void)
|
||||
{
|
||||
int count = 0;
|
||||
int count = 0, total = 0;
|
||||
|
||||
(void) iter_handlers(print_device_handler, &count);
|
||||
(void) printf("\n");
|
||||
count = 0;
|
||||
if (count > 0) {
|
||||
total += count;
|
||||
(void) printf("\n");
|
||||
count = 0;
|
||||
}
|
||||
|
||||
(void) iter_handlers(print_data_handler, &count);
|
||||
(void) printf("\n");
|
||||
count = 0;
|
||||
if (count > 0) {
|
||||
total += count;
|
||||
(void) printf("\n");
|
||||
count = 0;
|
||||
}
|
||||
|
||||
(void) iter_handlers(print_panic_handler, &count);
|
||||
|
||||
return (count);
|
||||
return (count + total);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
@@ -627,6 +635,8 @@ main(int argc, char **argv)
|
||||
error = ECKSUM;
|
||||
} else if (strcasecmp(optarg, "nxio") == 0) {
|
||||
error = ENXIO;
|
||||
} else if (strcasecmp(optarg, "dtl") == 0) {
|
||||
error = ECHILD;
|
||||
} else {
|
||||
(void) fprintf(stderr, "invalid error type "
|
||||
"'%s': must be 'io', 'checksum' or "
|
||||
|
||||
+58
-20
@@ -202,12 +202,14 @@ get_usage(zpool_help_t idx) {
|
||||
return (gettext("\thistory [-il] [<pool>] ...\n"));
|
||||
case HELP_IMPORT:
|
||||
return (gettext("\timport [-d dir] [-D]\n"
|
||||
"\timport [-d dir | -c cachefile] [-n] -F <pool | id>\n"
|
||||
"\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n"
|
||||
"\timport [-o mntopts] [-o property=value] ... \n"
|
||||
"\t [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n"
|
||||
"\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
|
||||
"[-R root] [-F [-n]] -a\n"
|
||||
"\timport [-o mntopts] [-o property=value] ... \n"
|
||||
"\t [-d dir | -c cachefile] [-D] [-f] [-R root] "
|
||||
"<pool | id> [newpool]\n"));
|
||||
"\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
|
||||
"[-R root] [-F [-n]]\n"
|
||||
"\t <pool | id> [newpool]\n"));
|
||||
case HELP_IOSTAT:
|
||||
return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
|
||||
"[count]]\n"));
|
||||
@@ -1499,7 +1501,7 @@ show_import(nvlist_t *config)
|
||||
*/
|
||||
static int
|
||||
do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
||||
int force, nvlist_t *props, boolean_t do_verbatim)
|
||||
nvlist_t *props, int flags)
|
||||
{
|
||||
zpool_handle_t *zhp;
|
||||
char *name;
|
||||
@@ -1517,7 +1519,8 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
||||
(void) fprintf(stderr, gettext("cannot import '%s': pool "
|
||||
"is formatted using a newer ZFS version\n"), name);
|
||||
return (1);
|
||||
} else if (state != POOL_STATE_EXPORTED && !force) {
|
||||
} else if (state != POOL_STATE_EXPORTED &&
|
||||
!(flags & ZFS_IMPORT_ANY_HOST)) {
|
||||
uint64_t hostid;
|
||||
|
||||
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
|
||||
@@ -1551,7 +1554,7 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
||||
}
|
||||
}
|
||||
|
||||
if (zpool_import_props(g_zfs, config, newname, props, do_verbatim) != 0)
|
||||
if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
|
||||
return (1);
|
||||
|
||||
if (newname != NULL)
|
||||
@@ -1561,6 +1564,7 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
||||
return (1);
|
||||
|
||||
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
|
||||
!(flags & ZFS_IMPORT_ONLY) &&
|
||||
zpool_enable_datasets(zhp, mntopts, 0) != 0) {
|
||||
zpool_close(zhp);
|
||||
return (1);
|
||||
@@ -1602,6 +1606,11 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
||||
*
|
||||
* -n See if rewind would work, but don't actually rewind.
|
||||
*
|
||||
* -N Import the pool but don't mount datasets.
|
||||
*
|
||||
* -T Specify a starting txg to use for import. This option is
|
||||
* intentionally undocumented option for testing purposes.
|
||||
*
|
||||
* -a Import all pools found.
|
||||
*
|
||||
* -o Set property=value and/or temporary mount options (without '=').
|
||||
@@ -1620,7 +1629,6 @@ zpool_do_import(int argc, char **argv)
|
||||
boolean_t do_all = B_FALSE;
|
||||
boolean_t do_destroyed = B_FALSE;
|
||||
char *mntopts = NULL;
|
||||
boolean_t do_force = B_FALSE;
|
||||
nvpair_t *elem;
|
||||
nvlist_t *config;
|
||||
uint64_t searchguid = 0;
|
||||
@@ -1630,17 +1638,18 @@ zpool_do_import(int argc, char **argv)
|
||||
nvlist_t *policy = NULL;
|
||||
nvlist_t *props = NULL;
|
||||
boolean_t first;
|
||||
boolean_t do_verbatim = B_FALSE;
|
||||
int flags = ZFS_IMPORT_NORMAL;
|
||||
uint32_t rewind_policy = ZPOOL_NO_REWIND;
|
||||
boolean_t dryrun = B_FALSE;
|
||||
boolean_t do_rewind = B_FALSE;
|
||||
boolean_t xtreme_rewind = B_FALSE;
|
||||
uint64_t pool_state;
|
||||
uint64_t pool_state, txg = -1ULL;
|
||||
char *cachefile = NULL;
|
||||
importargs_t idata = { 0 };
|
||||
char *endptr;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, ":aCc:d:DEfFno:rR:VX")) != -1) {
|
||||
while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
do_all = B_TRUE;
|
||||
@@ -1665,14 +1674,20 @@ zpool_do_import(int argc, char **argv)
|
||||
do_destroyed = B_TRUE;
|
||||
break;
|
||||
case 'f':
|
||||
do_force = B_TRUE;
|
||||
flags |= ZFS_IMPORT_ANY_HOST;
|
||||
break;
|
||||
case 'F':
|
||||
do_rewind = B_TRUE;
|
||||
break;
|
||||
case 'm':
|
||||
flags |= ZFS_IMPORT_MISSING_LOG;
|
||||
break;
|
||||
case 'n':
|
||||
dryrun = B_TRUE;
|
||||
break;
|
||||
case 'N':
|
||||
flags |= ZFS_IMPORT_ONLY;
|
||||
break;
|
||||
case 'o':
|
||||
if ((propval = strchr(optarg, '=')) != NULL) {
|
||||
*propval = '\0';
|
||||
@@ -1696,8 +1711,18 @@ zpool_do_import(int argc, char **argv)
|
||||
ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
|
||||
goto error;
|
||||
break;
|
||||
case 'T':
|
||||
errno = 0;
|
||||
txg = strtoull(optarg, &endptr, 10);
|
||||
if (errno != 0 || *endptr != '\0') {
|
||||
(void) fprintf(stderr,
|
||||
gettext("invalid txg value\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND;
|
||||
break;
|
||||
case 'V':
|
||||
do_verbatim = B_TRUE;
|
||||
flags |= ZFS_IMPORT_VERBATIM;
|
||||
break;
|
||||
case 'X':
|
||||
xtreme_rewind = B_TRUE;
|
||||
@@ -1736,6 +1761,7 @@ zpool_do_import(int argc, char **argv)
|
||||
|
||||
/* In the future, we can capture further policy and include it here */
|
||||
if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 ||
|
||||
nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 ||
|
||||
nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0)
|
||||
goto error;
|
||||
|
||||
@@ -1869,7 +1895,7 @@ zpool_do_import(int argc, char **argv)
|
||||
|
||||
if (do_all) {
|
||||
err |= do_import(config, NULL, mntopts,
|
||||
do_force, props, do_verbatim);
|
||||
props, flags);
|
||||
} else {
|
||||
show_import(config);
|
||||
}
|
||||
@@ -1918,7 +1944,7 @@ zpool_do_import(int argc, char **argv)
|
||||
err = B_TRUE;
|
||||
} else {
|
||||
err |= do_import(found_config, argc == 1 ? NULL :
|
||||
argv[1], mntopts, do_force, props, do_verbatim);
|
||||
argv[1], mntopts, props, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3217,7 +3243,7 @@ void
|
||||
print_scan_status(pool_scan_stat_t *ps)
|
||||
{
|
||||
time_t start, end;
|
||||
uint64_t elapsed, mins_left;
|
||||
uint64_t elapsed, mins_left, hours_left;
|
||||
uint64_t pass_exam, examined, total;
|
||||
uint_t rate;
|
||||
double fraction_done;
|
||||
@@ -3294,15 +3320,24 @@ print_scan_status(pool_scan_stat_t *ps)
|
||||
rate = pass_exam / elapsed;
|
||||
rate = rate ? rate : 1;
|
||||
mins_left = ((total - examined) / rate) / 60;
|
||||
hours_left = mins_left / 60;
|
||||
|
||||
zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
|
||||
zfs_nicenum(total, total_buf, sizeof (total_buf));
|
||||
zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
|
||||
|
||||
(void) printf(gettext(" %s scanned out of %s at "
|
||||
"%s/s, %lluh%um to go\n"), examined_buf, total_buf, rate_buf,
|
||||
(u_longlong_t)(mins_left / 60),
|
||||
(uint_t)(mins_left % 60));
|
||||
/*
|
||||
* do not print estimated time if hours_left is more than 30 days
|
||||
*/
|
||||
(void) printf(gettext(" %s scanned out of %s at %s/s"),
|
||||
examined_buf, total_buf, rate_buf);
|
||||
if (hours_left < (30 * 24)) {
|
||||
(void) printf(gettext(", %lluh%um to go\n"),
|
||||
(u_longlong_t)hours_left, (uint_t)(mins_left % 60));
|
||||
} else {
|
||||
(void) printf(gettext(
|
||||
", (scan is slow, no estimated time)\n"));
|
||||
}
|
||||
|
||||
if (ps->pss_func == POOL_SCAN_RESILVER) {
|
||||
(void) printf(gettext(" %s resilvered, %.2f%% done\n"),
|
||||
@@ -4009,6 +4044,9 @@ zpool_do_upgrade(int argc, char **argv)
|
||||
(void) printf(gettext(" 25 Improved scrub stats\n"));
|
||||
(void) printf(gettext(" 26 Improved snapshot deletion "
|
||||
"performance\n"));
|
||||
(void) printf(gettext(" 27 Improved snapshot creation "
|
||||
"performance\n"));
|
||||
(void) printf(gettext(" 28 Multiple vdev replacements\n"));
|
||||
(void) printf(gettext("\nFor more information on a particular "
|
||||
"version, including supported releases,\n"));
|
||||
(void) printf(gettext("see the ZFS Administration Guide.\n\n"));
|
||||
|
||||
+46
-37
@@ -1102,7 +1102,7 @@ ztest_bt_bonus(dmu_buf_t *db)
|
||||
#define lrz_bonustype lr_rdev
|
||||
#define lrz_bonuslen lr_crtime[1]
|
||||
|
||||
static uint64_t
|
||||
static void
|
||||
ztest_log_create(ztest_ds_t *zd, dmu_tx_t *tx, lr_create_t *lr)
|
||||
{
|
||||
char *name = (void *)(lr + 1); /* name follows lr */
|
||||
@@ -1110,40 +1110,41 @@ ztest_log_create(ztest_ds_t *zd, dmu_tx_t *tx, lr_create_t *lr)
|
||||
itx_t *itx;
|
||||
|
||||
if (zil_replaying(zd->zd_zilog, tx))
|
||||
return (0);
|
||||
return;
|
||||
|
||||
itx = zil_itx_create(TX_CREATE, sizeof (*lr) + namesize);
|
||||
bcopy(&lr->lr_common + 1, &itx->itx_lr + 1,
|
||||
sizeof (*lr) + namesize - sizeof (lr_t));
|
||||
|
||||
return (zil_itx_assign(zd->zd_zilog, itx, tx));
|
||||
zil_itx_assign(zd->zd_zilog, itx, tx);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
ztest_log_remove(ztest_ds_t *zd, dmu_tx_t *tx, lr_remove_t *lr)
|
||||
static void
|
||||
ztest_log_remove(ztest_ds_t *zd, dmu_tx_t *tx, lr_remove_t *lr, uint64_t object)
|
||||
{
|
||||
char *name = (void *)(lr + 1); /* name follows lr */
|
||||
size_t namesize = strlen(name) + 1;
|
||||
itx_t *itx;
|
||||
|
||||
if (zil_replaying(zd->zd_zilog, tx))
|
||||
return (0);
|
||||
return;
|
||||
|
||||
itx = zil_itx_create(TX_REMOVE, sizeof (*lr) + namesize);
|
||||
bcopy(&lr->lr_common + 1, &itx->itx_lr + 1,
|
||||
sizeof (*lr) + namesize - sizeof (lr_t));
|
||||
|
||||
return (zil_itx_assign(zd->zd_zilog, itx, tx));
|
||||
itx->itx_oid = object;
|
||||
zil_itx_assign(zd->zd_zilog, itx, tx);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static void
|
||||
ztest_log_write(ztest_ds_t *zd, dmu_tx_t *tx, lr_write_t *lr)
|
||||
{
|
||||
itx_t *itx;
|
||||
itx_wr_state_t write_state = ztest_random(WR_NUM_STATES);
|
||||
|
||||
if (zil_replaying(zd->zd_zilog, tx))
|
||||
return (0);
|
||||
return;
|
||||
|
||||
if (lr->lr_length > ZIL_MAX_LOG_DATA)
|
||||
write_state = WR_INDIRECT;
|
||||
@@ -1166,37 +1167,39 @@ ztest_log_write(ztest_ds_t *zd, dmu_tx_t *tx, lr_write_t *lr)
|
||||
bcopy(&lr->lr_common + 1, &itx->itx_lr + 1,
|
||||
sizeof (*lr) - sizeof (lr_t));
|
||||
|
||||
return (zil_itx_assign(zd->zd_zilog, itx, tx));
|
||||
zil_itx_assign(zd->zd_zilog, itx, tx);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static void
|
||||
ztest_log_truncate(ztest_ds_t *zd, dmu_tx_t *tx, lr_truncate_t *lr)
|
||||
{
|
||||
itx_t *itx;
|
||||
|
||||
if (zil_replaying(zd->zd_zilog, tx))
|
||||
return (0);
|
||||
return;
|
||||
|
||||
itx = zil_itx_create(TX_TRUNCATE, sizeof (*lr));
|
||||
bcopy(&lr->lr_common + 1, &itx->itx_lr + 1,
|
||||
sizeof (*lr) - sizeof (lr_t));
|
||||
|
||||
return (zil_itx_assign(zd->zd_zilog, itx, tx));
|
||||
itx->itx_sync = B_FALSE;
|
||||
zil_itx_assign(zd->zd_zilog, itx, tx);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
static void
|
||||
ztest_log_setattr(ztest_ds_t *zd, dmu_tx_t *tx, lr_setattr_t *lr)
|
||||
{
|
||||
itx_t *itx;
|
||||
|
||||
if (zil_replaying(zd->zd_zilog, tx))
|
||||
return (0);
|
||||
return;
|
||||
|
||||
itx = zil_itx_create(TX_SETATTR, sizeof (*lr));
|
||||
bcopy(&lr->lr_common + 1, &itx->itx_lr + 1,
|
||||
sizeof (*lr) - sizeof (lr_t));
|
||||
|
||||
return (zil_itx_assign(zd->zd_zilog, itx, tx));
|
||||
itx->itx_sync = B_FALSE;
|
||||
zil_itx_assign(zd->zd_zilog, itx, tx);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1328,7 +1331,7 @@ ztest_replay_remove(ztest_ds_t *zd, lr_remove_t *lr, boolean_t byteswap)
|
||||
|
||||
VERIFY3U(0, ==, zap_remove(os, lr->lr_doid, name, tx));
|
||||
|
||||
(void) ztest_log_remove(zd, tx, lr);
|
||||
(void) ztest_log_remove(zd, tx, lr, object);
|
||||
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
@@ -2045,7 +2048,7 @@ ztest_zil_commit(ztest_ds_t *zd, uint64_t id)
|
||||
{
|
||||
zilog_t *zilog = zd->zd_zilog;
|
||||
|
||||
zil_commit(zilog, UINT64_MAX, ztest_random(ZTEST_OBJECTS));
|
||||
zil_commit(zilog, ztest_random(ZTEST_OBJECTS));
|
||||
|
||||
/*
|
||||
* Remember the committed values in zd, which is in parent/child
|
||||
@@ -2875,7 +2878,7 @@ ztest_snapshot_create(char *osname, uint64_t id)
|
||||
(u_longlong_t)id);
|
||||
|
||||
error = dmu_objset_snapshot(osname, strchr(snapname, '@') + 1,
|
||||
NULL, B_FALSE);
|
||||
NULL, NULL, B_FALSE, B_FALSE, -1);
|
||||
if (error == ENOSPC) {
|
||||
ztest_record_enospc(FTAG);
|
||||
return (B_FALSE);
|
||||
@@ -3080,7 +3083,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
|
||||
(void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu", clone1name, id);
|
||||
|
||||
error = dmu_objset_snapshot(osname, strchr(snap1name, '@')+1,
|
||||
NULL, B_FALSE);
|
||||
NULL, NULL, B_FALSE, B_FALSE, -1);
|
||||
if (error && error != EEXIST) {
|
||||
if (error == ENOSPC) {
|
||||
ztest_record_enospc(FTAG);
|
||||
@@ -3104,7 +3107,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
|
||||
}
|
||||
|
||||
error = dmu_objset_snapshot(clone1name, strchr(snap2name, '@')+1,
|
||||
NULL, B_FALSE);
|
||||
NULL, NULL, B_FALSE, B_FALSE, -1);
|
||||
if (error && error != EEXIST) {
|
||||
if (error == ENOSPC) {
|
||||
ztest_record_enospc(FTAG);
|
||||
@@ -3114,7 +3117,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
|
||||
}
|
||||
|
||||
error = dmu_objset_snapshot(clone1name, strchr(snap3name, '@')+1,
|
||||
NULL, B_FALSE);
|
||||
NULL, NULL, B_FALSE, B_FALSE, -1);
|
||||
if (error && error != EEXIST) {
|
||||
if (error == ENOSPC) {
|
||||
ztest_record_enospc(FTAG);
|
||||
@@ -4304,7 +4307,8 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
|
||||
* Create snapshot, clone it, mark snap for deferred destroy,
|
||||
* destroy clone, verify snap was also destroyed.
|
||||
*/
|
||||
error = dmu_objset_snapshot(osname, snapname, NULL, FALSE);
|
||||
error = dmu_objset_snapshot(osname, snapname, NULL, NULL, FALSE,
|
||||
FALSE, -1);
|
||||
if (error) {
|
||||
if (error == ENOSPC) {
|
||||
ztest_record_enospc("dmu_objset_snapshot");
|
||||
@@ -4346,7 +4350,8 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
|
||||
* destroy a held snapshot, mark for deferred destroy,
|
||||
* release hold, verify snapshot was destroyed.
|
||||
*/
|
||||
error = dmu_objset_snapshot(osname, snapname, NULL, FALSE);
|
||||
error = dmu_objset_snapshot(osname, snapname, NULL, NULL, FALSE,
|
||||
FALSE, -1);
|
||||
if (error) {
|
||||
if (error == ENOSPC) {
|
||||
ztest_record_enospc("dmu_objset_snapshot");
|
||||
@@ -4355,7 +4360,8 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
|
||||
fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error);
|
||||
}
|
||||
|
||||
error = dsl_dataset_user_hold(osname, snapname, tag, B_FALSE, B_TRUE);
|
||||
error = dsl_dataset_user_hold(osname, snapname, tag, B_FALSE,
|
||||
B_TRUE, -1);
|
||||
if (error)
|
||||
fatal(0, "dsl_dataset_user_hold(%s)", fullname, tag);
|
||||
|
||||
@@ -4843,19 +4849,19 @@ ztest_spa_import_export(char *oldname, char *newname)
|
||||
/*
|
||||
* Import it under the new name.
|
||||
*/
|
||||
VERIFY3U(0, ==, spa_import(newname, config, NULL));
|
||||
VERIFY3U(0, ==, spa_import(newname, config, NULL, 0));
|
||||
|
||||
ztest_walk_pool_directory("pools after import");
|
||||
|
||||
/*
|
||||
* Try to import it again -- should fail with EEXIST.
|
||||
*/
|
||||
VERIFY3U(EEXIST, ==, spa_import(newname, config, NULL));
|
||||
VERIFY3U(EEXIST, ==, spa_import(newname, config, NULL, 0));
|
||||
|
||||
/*
|
||||
* Try to import it under a different name -- should fail with EEXIST.
|
||||
*/
|
||||
VERIFY3U(EEXIST, ==, spa_import(oldname, config, NULL));
|
||||
VERIFY3U(EEXIST, ==, spa_import(oldname, config, NULL, 0));
|
||||
|
||||
/*
|
||||
* Verify that the pool is no longer visible under the old name.
|
||||
@@ -5242,6 +5248,13 @@ ztest_run(ztest_shared_t *zs)
|
||||
}
|
||||
|
||||
kernel_fini();
|
||||
|
||||
list_destroy(&zcl.zcl_callbacks);
|
||||
|
||||
(void) _mutex_destroy(&zcl.zcl_callbacks_lock);
|
||||
|
||||
(void) rwlock_destroy(&zs->zs_name_lock);
|
||||
(void) _mutex_destroy(&zs->zs_vdev_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -5265,7 +5278,7 @@ ztest_freeze(ztest_shared_t *zs)
|
||||
*/
|
||||
while (BP_IS_HOLE(&zd->zd_zilog->zl_header->zh_log)) {
|
||||
ztest_dmu_object_alloc_free(zd, 0);
|
||||
zil_commit(zd->zd_zilog, UINT64_MAX, 0);
|
||||
zil_commit(zd->zd_zilog, 0);
|
||||
}
|
||||
|
||||
txg_wait_synced(spa_get_dsl(spa), 0);
|
||||
@@ -5292,7 +5305,7 @@ ztest_freeze(ztest_shared_t *zs)
|
||||
/*
|
||||
* Commit all of the changes we just generated.
|
||||
*/
|
||||
zil_commit(zd->zd_zilog, UINT64_MAX, 0);
|
||||
zil_commit(zd->zd_zilog, 0);
|
||||
txg_wait_synced(spa_get_dsl(spa), 0);
|
||||
|
||||
/*
|
||||
@@ -5311,13 +5324,6 @@ ztest_freeze(ztest_shared_t *zs)
|
||||
ztest_dataset_close(zs, 0);
|
||||
spa_close(spa, FTAG);
|
||||
kernel_fini();
|
||||
|
||||
list_destroy(&zcl.zcl_callbacks);
|
||||
|
||||
(void) _mutex_destroy(&zcl.zcl_callbacks_lock);
|
||||
|
||||
(void) rwlock_destroy(&zs->zs_name_lock);
|
||||
(void) _mutex_destroy(&zs->zs_vdev_lock);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -5401,6 +5407,9 @@ ztest_init(ztest_shared_t *zs)
|
||||
ztest_freeze(zs);
|
||||
|
||||
ztest_run_zdb(zs->zs_pool);
|
||||
|
||||
(void) rwlock_destroy(&zs->zs_name_lock);
|
||||
(void) _mutex_destroy(&zs->zs_vdev_lock);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user