summaryrefslogtreecommitdiffstats
path: root/cddl/contrib
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2007-05-06 01:39:39 +0000
committerpjd <pjd@FreeBSD.org>2007-05-06 01:39:39 +0000
commit1effa32b6605b4852fd2e5c00bd93f04f0e3bf60 (patch)
tree155527b23b9a27cd3b08983c2dbd01ca5b09866d /cddl/contrib
parenta360ad79b03fc86ad14ee529259ec67558935c3c (diff)
downloadFreeBSD-src-1effa32b6605b4852fd2e5c00bd93f04f0e3bf60.zip
FreeBSD-src-1effa32b6605b4852fd2e5c00bd93f04f0e3bf60.tar.gz
Use provider's ident to handle situations when disks are moved around
and show up with different names: first try to open provider using remembered name and compare its ident, if equal, this is our provider, if not equal or there is no provider with such name, find provider with remembered ident and don't care about the name.
Diffstat (limited to 'cddl/contrib')
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c
index de07723..cfed1f0 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c
@@ -159,18 +159,14 @@ out:
static boolean_t
is_provider(const char *name)
{
- off_t mediasize;
int fd;
- fd = open(name, O_RDONLY);
- if (fd == -1)
- return (B_FALSE);
- if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) == -1) {
- close(fd);
- return (B_FALSE);
+ fd = g_open(name, 0);
+ if (fd >= 0) {
+ g_close(fd);
+ return (B_TRUE);
}
- close(fd);
- return (B_TRUE);
+ return (B_FALSE);
}
/*
@@ -183,9 +179,11 @@ is_provider(const char *name)
nvlist_t *
make_leaf_vdev(const char *arg)
{
- char path[MAXPATHLEN];
+ char ident[DISK_IDENT_SIZE], path[MAXPATHLEN];
+ struct stat64 statbuf;
nvlist_t *vdev = NULL;
char *type = NULL;
+ boolean_t wholedisk = B_FALSE;
if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
strlcpy(path, arg, sizeof (path));
@@ -212,6 +210,41 @@ make_leaf_vdev(const char *arg)
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
(uint64_t)B_FALSE) == 0);
+ /*
+ * For a whole disk, defer getting its devid until after labeling it.
+ */
+ if (1 || (S_ISBLK(statbuf.st_mode) && !wholedisk)) {
+ /*
+ * Get the devid for the device.
+ */
+ int fd;
+ ddi_devid_t devid;
+ char *minor = NULL, *devid_str = NULL;
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ (void) fprintf(stderr, gettext("cannot open '%s': "
+ "%s\n"), path, strerror(errno));
+ nvlist_free(vdev);
+ return (NULL);
+ }
+
+ if (devid_get(fd, &devid) == 0) {
+ if (devid_get_minor_name(fd, &minor) == 0 &&
+ (devid_str = devid_str_encode(devid, minor)) !=
+ NULL) {
+ verify(nvlist_add_string(vdev,
+ ZPOOL_CONFIG_DEVID, devid_str) == 0);
+ }
+ if (devid_str != NULL)
+ devid_str_free(devid_str);
+ if (minor != NULL)
+ devid_str_free(minor);
+ devid_free(devid);
+ }
+
+ (void) close(fd);
+ }
+
return (vdev);
}
OpenPOWER on IntegriCloud