mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-18 15:30:21 +00:00
MFV r297760: 6418 zpool should have a label clearing command
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Author: Will Andrews <will@firepipe.net> Closes #83 Closes #32 openzfs/openzfs@9663688425 FreeBSD already had `zpool labelclear` functionality, so this is mostly just a diff reduction. MFC after: 1 month
This commit is contained in:
commit
eaee150e3f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=297763
@ -2156,10 +2156,11 @@ dump_label(const char *dev)
|
||||
uint64_t psize, ashift;
|
||||
int len = strlen(dev) + 1;
|
||||
|
||||
if (strncmp(dev, "/dev/dsk/", 9) == 0) {
|
||||
if (strncmp(dev, ZFS_DISK_ROOTD, strlen(ZFS_DISK_ROOTD)) == 0) {
|
||||
len++;
|
||||
path = malloc(len);
|
||||
(void) snprintf(path, len, "%s%s", "/dev/rdsk/", dev + 9);
|
||||
(void) snprintf(path, len, "%s%s", ZFS_RDISK_ROOTD,
|
||||
dev + strlen(ZFS_DISK_ROOTD));
|
||||
} else {
|
||||
path = strdup(dev);
|
||||
}
|
||||
|
@ -21,12 +21,12 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012 by Frederik Wessels. All rights reserved.
|
||||
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||
* Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
|
||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
||||
* Copyright 2016 Nexenta Systems, Inc.
|
||||
*/
|
||||
|
||||
#include <solaris.h>
|
||||
@ -626,7 +626,10 @@ zpool_do_remove(int argc, char **argv)
|
||||
}
|
||||
|
||||
/*
|
||||
* zpool labelclear <vdev>
|
||||
* zpool labelclear [-f] <vdev>
|
||||
*
|
||||
* -f Force clearing the label for the vdevs which are members of
|
||||
* the exported or foreign pools.
|
||||
*
|
||||
* Verifies that the vdev is not active and zeros out the label information
|
||||
* on the device.
|
||||
@ -634,8 +637,11 @@ zpool_do_remove(int argc, char **argv)
|
||||
int
|
||||
zpool_do_labelclear(int argc, char **argv)
|
||||
{
|
||||
char *vdev, *name;
|
||||
int c, fd = -1, ret = 0;
|
||||
char vdev[MAXPATHLEN];
|
||||
char *name = NULL;
|
||||
struct stat st;
|
||||
int c, fd, ret = 0;
|
||||
nvlist_t *config;
|
||||
pool_state_t state;
|
||||
boolean_t inuse = B_FALSE;
|
||||
boolean_t force = B_FALSE;
|
||||
@ -658,88 +664,110 @@ zpool_do_labelclear(int argc, char **argv)
|
||||
|
||||
/* get vdev name */
|
||||
if (argc < 1) {
|
||||
(void) fprintf(stderr, gettext("missing vdev device name\n"));
|
||||
(void) fprintf(stderr, gettext("missing vdev name\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
if (argc > 1) {
|
||||
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||
usage(B_FALSE);
|
||||
}
|
||||
|
||||
vdev = argv[0];
|
||||
if ((fd = open(vdev, O_RDWR)) < 0) {
|
||||
(void) fprintf(stderr, gettext("Unable to open %s\n"), vdev);
|
||||
return (B_FALSE);
|
||||
}
|
||||
/*
|
||||
* Check if we were given absolute path and use it as is.
|
||||
* Otherwise if the provided vdev name doesn't point to a file,
|
||||
* try prepending dsk path and appending s0.
|
||||
*/
|
||||
(void) strlcpy(vdev, argv[0], sizeof (vdev));
|
||||
if (vdev[0] != '/' && stat(vdev, &st) != 0) {
|
||||
char *s;
|
||||
|
||||
name = NULL;
|
||||
if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) != 0) {
|
||||
if (force)
|
||||
goto wipe_label;
|
||||
|
||||
(void) fprintf(stderr,
|
||||
gettext("Unable to determine pool state for %s\n"
|
||||
"Use -f to force the clearing any label data\n"), vdev);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (inuse) {
|
||||
switch (state) {
|
||||
default:
|
||||
case POOL_STATE_ACTIVE:
|
||||
case POOL_STATE_SPARE:
|
||||
case POOL_STATE_L2CACHE:
|
||||
(void) fprintf(stderr,
|
||||
gettext("labelclear operation failed.\n"
|
||||
"\tVdev %s is a member (%s), of pool \"%s\".\n"
|
||||
"\tTo remove label information from this device, export or destroy\n"
|
||||
"\tthe pool, or remove %s from the configuration of this pool\n"
|
||||
"\tand retry the labelclear operation\n"),
|
||||
vdev, zpool_pool_state_to_name(state), name, vdev);
|
||||
ret = 1;
|
||||
goto errout;
|
||||
|
||||
case POOL_STATE_EXPORTED:
|
||||
if (force)
|
||||
break;
|
||||
|
||||
(void) fprintf(stderr,
|
||||
gettext("labelclear operation failed.\n"
|
||||
"\tVdev %s is a member of the exported pool \"%s\".\n"
|
||||
"\tUse \"zpool labelclear -f %s\" to force the removal of label\n"
|
||||
"\tinformation.\n"),
|
||||
vdev, name, vdev);
|
||||
ret = 1;
|
||||
goto errout;
|
||||
|
||||
case POOL_STATE_POTENTIALLY_ACTIVE:
|
||||
if (force)
|
||||
break;
|
||||
|
||||
(void) fprintf(stderr,
|
||||
gettext("labelclear operation failed.\n"
|
||||
"\tVdev %s is a member of the pool \"%s\".\n"
|
||||
"\tThis pool is unknown to this system, but may be active on\n"
|
||||
"\tanother system. Use \'zpool labelclear -f %s\' to force the\n"
|
||||
"\tremoval of label information.\n"),
|
||||
vdev, name, vdev);
|
||||
ret = 1;
|
||||
goto errout;
|
||||
|
||||
case POOL_STATE_DESTROYED:
|
||||
/* inuse should never be set for a destoryed pool... */
|
||||
break;
|
||||
(void) snprintf(vdev, sizeof (vdev), "%s/%s",
|
||||
#ifdef illumos
|
||||
ZFS_DISK_ROOT, argv[0]);
|
||||
if ((s = strrchr(argv[0], 's')) == NULL ||
|
||||
!isdigit(*(s + 1)))
|
||||
(void) strlcat(vdev, "s0", sizeof (vdev));
|
||||
#else
|
||||
"/dev", argv[0]);
|
||||
#endif
|
||||
if (stat(vdev, &st) != 0) {
|
||||
(void) fprintf(stderr, gettext(
|
||||
"failed to find device %s, try specifying absolute "
|
||||
"path instead\n"), argv[0]);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
wipe_label:
|
||||
if (zpool_clear_label(fd) != 0) {
|
||||
if ((fd = open(vdev, O_RDWR)) < 0) {
|
||||
(void) fprintf(stderr, gettext("failed to open %s: %s\n"),
|
||||
vdev, strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (zpool_read_label(fd, &config) != 0 || config == NULL) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("Label clear failed on vdev %s\n"), vdev);
|
||||
gettext("failed to read label from %s\n"), vdev);
|
||||
return (1);
|
||||
}
|
||||
nvlist_free(config);
|
||||
|
||||
ret = zpool_in_use(g_zfs, fd, &state, &name, &inuse);
|
||||
if (ret != 0) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("failed to check state for %s\n"), vdev);
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!inuse)
|
||||
goto wipe_label;
|
||||
|
||||
switch (state) {
|
||||
default:
|
||||
case POOL_STATE_ACTIVE:
|
||||
case POOL_STATE_SPARE:
|
||||
case POOL_STATE_L2CACHE:
|
||||
(void) fprintf(stderr, gettext(
|
||||
"%s is a member (%s) of pool \"%s\"\n"),
|
||||
vdev, zpool_pool_state_to_name(state), name);
|
||||
ret = 1;
|
||||
goto errout;
|
||||
|
||||
case POOL_STATE_EXPORTED:
|
||||
if (force)
|
||||
break;
|
||||
(void) fprintf(stderr, gettext(
|
||||
"use '-f' to override the following error:\n"
|
||||
"%s is a member of exported pool \"%s\"\n"),
|
||||
vdev, name);
|
||||
ret = 1;
|
||||
goto errout;
|
||||
|
||||
case POOL_STATE_POTENTIALLY_ACTIVE:
|
||||
if (force)
|
||||
break;
|
||||
(void) fprintf(stderr, gettext(
|
||||
"use '-f' to override the following error:\n"
|
||||
"%s is a member of potentially active pool \"%s\"\n"),
|
||||
vdev, name);
|
||||
ret = 1;
|
||||
goto errout;
|
||||
|
||||
case POOL_STATE_DESTROYED:
|
||||
/* inuse should never be set for a destroyed pool */
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
wipe_label:
|
||||
ret = zpool_clear_label(fd);
|
||||
if (ret != 0) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("failed to clear label for %s\n"), vdev);
|
||||
}
|
||||
|
||||
errout:
|
||||
close(fd);
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
free(name);
|
||||
(void) close(fd);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
@ -79,8 +79,6 @@
|
||||
|
||||
#include "zpool_util.h"
|
||||
|
||||
#define DISK_ROOT "/dev/dsk"
|
||||
#define RDISK_ROOT "/dev/rdsk"
|
||||
#define BACKUP_SLICE "s2"
|
||||
|
||||
/*
|
||||
@ -384,7 +382,7 @@ is_whole_disk(const char *arg)
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
(void) snprintf(path, sizeof (path), "%s%s%s",
|
||||
RDISK_ROOT, strrchr(arg, '/'), BACKUP_SLICE);
|
||||
ZFS_RDISK_ROOT, strrchr(arg, '/'), BACKUP_SLICE);
|
||||
if ((fd = open(path, O_RDWR | O_NDELAY)) < 0)
|
||||
return (B_FALSE);
|
||||
if (efi_alloc_and_init(fd, EFI_NUMPAR, &label) != 0) {
|
||||
|
@ -20,10 +20,10 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||
* Copyright 2015 RackTop Systems.
|
||||
* Copyright 2016 Nexenta Systems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1099,9 +1099,7 @@ zpool_open_func(void *arg)
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a file descriptor, clear (zero) the label information. This function
|
||||
* is used in the appliance stack as part of the ZFS sysevent module and
|
||||
* to implement the "zpool labelclear" command.
|
||||
* Given a file descriptor, clear (zero) the label information.
|
||||
*/
|
||||
int
|
||||
zpool_clear_label(int fd)
|
||||
@ -1168,7 +1166,7 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg)
|
||||
*/
|
||||
for (i = 0; i < dirs; i++) {
|
||||
tpool_t *t;
|
||||
char *rdsk;
|
||||
char rdsk[MAXPATHLEN];
|
||||
int dfd;
|
||||
boolean_t config_failed = B_FALSE;
|
||||
DIR *dirp;
|
||||
@ -1184,15 +1182,17 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg)
|
||||
*end = 0;
|
||||
pathleft = &path[sizeof (path)] - end;
|
||||
|
||||
#ifdef illumos
|
||||
/*
|
||||
* Using raw devices instead of block devices when we're
|
||||
* reading the labels skips a bunch of slow operations during
|
||||
* close(2) processing, so we replace /dev/dsk with /dev/rdsk.
|
||||
*/
|
||||
if (strcmp(path, "/dev/dsk/") == 0)
|
||||
rdsk = "/dev/";
|
||||
if (strcmp(path, ZFS_DISK_ROOTD) == 0)
|
||||
(void) strlcpy(rdsk, ZFS_RDISK_ROOTD, sizeof (rdsk));
|
||||
else
|
||||
rdsk = path;
|
||||
#endif
|
||||
(void) strlcpy(rdsk, path, sizeof (rdsk));
|
||||
|
||||
if ((dfd = open64(rdsk, O_RDONLY)) < 0 ||
|
||||
(dirp = fdopendir(dfd)) == NULL) {
|
||||
|
@ -20,10 +20,10 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||
* Copyright 2016 Nexenta Systems, Inc.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -49,8 +49,6 @@
|
||||
|
||||
static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
|
||||
|
||||
#define DISK_ROOT "/dev/dsk"
|
||||
#define RDISK_ROOT "/dev/rdsk"
|
||||
#define BACKUP_SLICE "s2"
|
||||
|
||||
typedef struct prop_flags {
|
||||
@ -2345,7 +2343,7 @@ zpool_relabel_disk(libzfs_handle_t *hdl, const char *name)
|
||||
"efi_use_whole_disk")) == NULL)
|
||||
return (-1);
|
||||
|
||||
(void) snprintf(path, sizeof (path), "%s/%s", RDISK_ROOT, name);
|
||||
(void) snprintf(path, sizeof (path), "%s/%s", ZFS_RDISK_ROOT, name);
|
||||
|
||||
if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
|
||||
@ -2421,7 +2419,7 @@ zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
|
||||
}
|
||||
|
||||
if (wholedisk) {
|
||||
pathname += strlen(DISK_ROOT) + 1;
|
||||
pathname += strlen(ZFS_DISK_ROOT) + 1;
|
||||
(void) zpool_relabel_disk(hdl, pathname);
|
||||
}
|
||||
}
|
||||
@ -3411,8 +3409,8 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
|
||||
}
|
||||
|
||||
#ifdef illumos
|
||||
if (strncmp(path, "/dev/dsk/", 9) == 0)
|
||||
path += 9;
|
||||
if (strncmp(path, ZFS_DISK_ROOTD, strlen(ZFS_DISK_ROOTD)) == 0)
|
||||
path += strlen(ZFS_DISK_ROOTD);
|
||||
|
||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
|
||||
&value) == 0 && value) {
|
||||
@ -3846,7 +3844,7 @@ read_efi_label(nvlist_t *config, diskaddr_t *sb)
|
||||
if (nvlist_lookup_string(config, ZPOOL_CONFIG_PATH, &path) != 0)
|
||||
return (err);
|
||||
|
||||
(void) snprintf(diskname, sizeof (diskname), "%s%s", RDISK_ROOT,
|
||||
(void) snprintf(diskname, sizeof (diskname), "%s%s", ZFS_RDISK_ROOT,
|
||||
strrchr(path, '/'));
|
||||
if ((fd = open(diskname, O_RDONLY|O_NDELAY)) >= 0) {
|
||||
struct dk_gpt *vtoc;
|
||||
@ -3931,7 +3929,7 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
|
||||
start_block = NEW_START_BLOCK;
|
||||
}
|
||||
|
||||
(void) snprintf(path, sizeof (path), "%s/%s%s", RDISK_ROOT, name,
|
||||
(void) snprintf(path, sizeof (path), "%s/%s%s", ZFS_RDISK_ROOT, name,
|
||||
BACKUP_SLICE);
|
||||
|
||||
if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
|
||||
|
@ -785,6 +785,10 @@ typedef struct ddt_histogram {
|
||||
#define ZFS_DRIVER "zfs"
|
||||
#define ZFS_DEV_NAME "zfs"
|
||||
#define ZFS_DEV "/dev/" ZFS_DEV_NAME
|
||||
#define ZFS_DISK_ROOT "/dev/dsk"
|
||||
#define ZFS_DISK_ROOTD ZFS_DISK_ROOT "/"
|
||||
#define ZFS_RDISK_ROOT "/dev/rdsk"
|
||||
#define ZFS_RDISK_ROOTD ZFS_RDISK_ROOT "/"
|
||||
|
||||
/* general zvol path */
|
||||
#define ZVOL_DIR "/dev/zvol"
|
||||
|
Loading…
Reference in New Issue
Block a user