Merge branch 'linux-user-disk' into refs/top-bases/linux-zfs-branch
This commit is contained in:
commit
e0e0bac5a6
|
@ -279,7 +279,7 @@ check_disk(const char *path, blkid_cache cache, int force,
|
|||
* label at the end of the device is intact. Rather than use this
|
||||
* label we should play it safe and treat this as a non efi device.
|
||||
*/
|
||||
if (vtoc->efi_flags & EFI_GPT_PRIMARY_CORRUPT) {
|
||||
if (!force && vtoc->efi_flags & EFI_GPT_PRIMARY_CORRUPT) {
|
||||
vdev_error(gettext(
|
||||
"%s contains a corrupt primary efi partition table. "
|
||||
"If you are\nsure you want to use this device use "
|
||||
|
@ -938,12 +938,7 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv)
|
|||
char *type, *path, *diskname;
|
||||
char buf[MAXPATHLEN];
|
||||
uint64_t wholedisk;
|
||||
int fd;
|
||||
int ret;
|
||||
#if defined(__sun__) || defined(__sun)
|
||||
ddi_devid_t devid;
|
||||
char *minor = NULL, *devid_str = NULL;
|
||||
#endif
|
||||
|
||||
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
|
||||
|
||||
|
@ -983,50 +978,34 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv)
|
|||
return (-1);
|
||||
|
||||
/*
|
||||
* Fill in the devid, now that we've labeled the disk. We
|
||||
* attempt to open the new zfs slice first by appending the
|
||||
* slice number. If that fails this may be a Linux udev
|
||||
* path in which case the -part# convention is tried.
|
||||
* Now the we've labeled the disk and the partitions have
|
||||
* been created. We still need to wait for udev to create
|
||||
* the symlinks to those partitions. If we are accessing
|
||||
* the devices via a udev disk path, /dev/disk, then wait
|
||||
* for *-part# to be created. Otherwise just use the normal
|
||||
* syntax for devices in /dev.
|
||||
*/
|
||||
(void) snprintf(buf, sizeof (buf), "%s%s", path, FIRST_SLICE);
|
||||
if ((fd = open(buf, O_RDONLY)) < 0) {
|
||||
if (strncmp(path, UDISK_ROOT, strlen(UDISK_ROOT)) == 0)
|
||||
(void) snprintf(buf, sizeof (buf),
|
||||
"%s%s%s", path, "-part", FIRST_SLICE);
|
||||
else
|
||||
(void) snprintf(buf, sizeof (buf),
|
||||
"%s%s", path, FIRST_SLICE);
|
||||
|
||||
(void) snprintf(buf, sizeof (buf), "%s%s%s",
|
||||
path, "-part", FIRST_SLICE);
|
||||
if ((fd = open(buf, O_RDONLY)) < 0) {
|
||||
(void) fprintf(stderr,
|
||||
gettext("cannot open '%s': %s\n"),
|
||||
buf, strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
if ((ret = zpool_label_disk_wait(buf, 1000)) != 0) {
|
||||
(void) fprintf(stderr,
|
||||
gettext( "cannot resolve path '%s'\n"), buf);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if defined(__sun__) || defined(__sun)
|
||||
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(nv,
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update the path to refer to the 's0' slice. The presence of
|
||||
* Update the path to refer to FIRST_SLICE. The presence of
|
||||
* the 'whole_disk' field indicates to the CLI that we should
|
||||
* chop off the slice number when displaying the device in
|
||||
* future output.
|
||||
*/
|
||||
verify(nvlist_add_string(nv, ZPOOL_CONFIG_PATH, buf) == 0);
|
||||
|
||||
(void) close(fd);
|
||||
|
||||
/* Just in case this partition already existed. */
|
||||
(void) zero_label(buf);
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ extern "C" {
|
|||
#if defined(__sun__) || defined(__sun)
|
||||
#define DISK_ROOT "/dev/dsk"
|
||||
#define RDISK_ROOT "/dev/rdsk"
|
||||
#define UDISK_ROOT RDISK_ROOT
|
||||
#define FIRST_SLICE "s0"
|
||||
#define BACKUP_SLICE "s2"
|
||||
#endif
|
||||
|
@ -63,6 +64,7 @@ extern "C" {
|
|||
#ifdef __linux__
|
||||
#define DISK_ROOT "/dev"
|
||||
#define RDISK_ROOT DISK_ROOT
|
||||
#define UDISK_ROOT "/dev/disk"
|
||||
#define FIRST_SLICE "1"
|
||||
#define BACKUP_SLICE ""
|
||||
#endif
|
||||
|
@ -253,6 +255,7 @@ extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *,
|
|||
boolean_t *, boolean_t *);
|
||||
extern nvlist_t *zpool_find_vdev_by_physpath(zpool_handle_t *, const char *,
|
||||
boolean_t *, boolean_t *, boolean_t *);
|
||||
extern int zpool_label_disk_wait(char *, int);
|
||||
extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, char *);
|
||||
|
||||
/*
|
||||
|
|
|
@ -3118,6 +3118,33 @@ find_start_block(nvlist_t *config)
|
|||
return (MAXOFFSET_T);
|
||||
}
|
||||
|
||||
int
|
||||
zpool_label_disk_wait(char *path, int timeout)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
struct stat64 statbuf;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Wait timeout miliseconds for a newly created device to be available
|
||||
* from the given path. There is a small window when a /dev/ device
|
||||
* will exist and the udev link will not, so we must wait for the
|
||||
* symlink. Depending on the udev rules this may take a few seconds.
|
||||
*/
|
||||
for (i = 0; i < timeout; i++) {
|
||||
usleep(1000);
|
||||
|
||||
errno = 0;
|
||||
if ((stat64(path, &statbuf) == 0) && (errno == 0))
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (ENOENT);
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Label an individual disk. The name provided is the short name,
|
||||
* stripped of any leading /dev path.
|
||||
|
@ -3132,10 +3159,7 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name)
|
|||
uint64_t slice_size;
|
||||
diskaddr_t start_block;
|
||||
char errbuf[1024];
|
||||
#if defined(__linux__)
|
||||
struct stat64 statbuf;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* prepare an error message just in case */
|
||||
(void) snprintf(errbuf, sizeof (errbuf),
|
||||
dgettext(TEXT_DOMAIN, "cannot label '%s'"), name);
|
||||
|
@ -3235,23 +3259,13 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name)
|
|||
efi_free(vtoc);
|
||||
|
||||
#if defined(__linux__)
|
||||
/*
|
||||
* The efi partition table has been successfully written and the
|
||||
* kernel notified. However, it still may take a moment for udev
|
||||
* to notice the devfs update and properly populate /dev/. We will
|
||||
* wait up to 3 seconds which is far far far longer than needed.
|
||||
*/
|
||||
(void) snprintf(path, sizeof (path), "%s/%s%s", RDISK_ROOT, name,
|
||||
FIRST_SLICE);
|
||||
for (i = 0; i < 3000; i++) {
|
||||
if (stat64(path, &statbuf) == 0 || errno != ENOENT)
|
||||
break;
|
||||
|
||||
usleep(1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Wait for the first expected slice to appear */
|
||||
(void) snprintf(path, sizeof (path), "%s/%s%s",
|
||||
DISK_ROOT, name, FIRST_SLICE);
|
||||
return zpool_label_disk_wait(path, 3000);
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
|
|
Loading…
Reference in New Issue