示例#1
0
static vdev_t *
vdev_lookup_by_path(vdev_t *vd, const char *name)
{
	vdev_t *mvd;
	int c;
	char pathbuf[MAXPATHLEN];
	char *lookup_name;
	int err = 0;

	if (!vd) return NULL;

	// Check both strings are valid
	if (name && *name &&
		vd->vdev_path && vd->vdev_path[0]) {
		int off;
		struct vnode *vp;

		lookup_name = vd->vdev_path;

		// We need to resolve symlinks here to get the final source name
		dprintf("ZFS: Looking up '%s'\n", vd->vdev_path);

		if ((err = vnode_lookup(vd->vdev_path, 0,
								&vp, vfs_context_current())) == 0) {
			int len = MAXPATHLEN;

			if ((err = vn_getpath(vp, pathbuf, &len)) == 0) {
				dprintf("ZFS: '%s' resolved name is '%s'\n",
						vd->vdev_path, pathbuf);
				lookup_name = pathbuf;
			}

			vnode_put(vp);
		}

		if (err) dprintf("ZFS: Lookup failed %d\n", err);

		// Skip /dev/ or not?
		strncmp("/dev/", lookup_name, 5) == 0 ? off=5 : off=0;

		dprintf("ZFS: vdev '%s' == '%s' ?\n", name,
				&lookup_name[off]);

		if (!strcmp(name, &lookup_name[off])) return vd;
	}

	for (c = 0; c < vd->vdev_children; c++)
		if ((mvd = vdev_lookup_by_path(vd->vdev_child[c], name)) !=
			NULL)
			return (mvd);

	return (NULL);
}
示例#2
0
文件: zfs_osx.cpp 项目: rottegift/zfs
static vdev_t *
vdev_lookup_by_path(vdev_t *vd, const char *name)
{
    vdev_t *mvd;
    int c;
    char *lookup_name;
    vdev_disk_t *dvd = NULL;

    if (!vd) return NULL;

    dvd = (vdev_disk_t *)vd->vdev_tsd;

    // Check both strings are valid
    if (name && *name && dvd &&
            vd->vdev_path && vd->vdev_path[0]) {
        int off;

        // Try normal path "vdev_path" or the readlink resolved

        lookup_name = vd->vdev_path;

        // Skip /dev/ or not?
        strncmp("/dev/", lookup_name, 5) == 0 ? off=5 : off=0;

        dprintf("ZFS: vdev '%s' == '%s' ?\n", name,
                &lookup_name[off]);

        if (!strcmp(name, &lookup_name[off])) return vd;


        lookup_name = dvd->vd_readlinkname;

        // Skip /dev/ or not?
        strncmp("/dev/", lookup_name, 5) == 0 ? off=5 : off=0;

        dprintf("ZFS: vdev '%s' == '%s' ?\n", name,
                &lookup_name[off]);

        if (!strcmp(name, &lookup_name[off])) return vd;
    }

    for (c = 0; c < vd->vdev_children; c++)
        if ((mvd = vdev_lookup_by_path(vd->vdev_child[c], name)) !=
                NULL)
            return (mvd);

    return (NULL);
}
示例#3
0
/*
 * Callback for device termination events, ie, disks removed.
 */
bool IOkit_disk_removed_callback(void* target,
								 void* refCon,
								 IOService* newService,
								 IONotifier* notifier)
{
	OSObject *prop = 0;
	OSString* bsdnameosstr = 0;

	prop = newService->getProperty(kIOBSDNameKey, gIOServicePlane,
								   kIORegistryIterateRecursively);
	if (prop) {
		spa_t *spa = NULL;

		bsdnameosstr = OSDynamicCast(OSString, prop);
		printf("ZFS: Device removal detected: '%s'\n",
			   bsdnameosstr->getCStringNoCopy());

		for (spa = spa_next(NULL);
			 spa != NULL; spa = spa_next(spa)) {
		  vdev_t *vd;

		  dprintf("ZFS: Scanning pool '%s'\n", spa_name(spa));

		  vd = vdev_lookup_by_path(spa->spa_root_vdev,
								   bsdnameosstr->getCStringNoCopy());

		  if (vd && vd->vdev_path) {

			printf("ZFS: Device '%s' removal requested\n",
				   vd->vdev_path);
			(void) thread_create(NULL, 0, vdev_close_thread,
								 vd, 0, &p0,
								 TS_RUN, minclsyspri);

			vd->vdev_remove_wanted = B_TRUE;
			spa_async_request(spa, SPA_ASYNC_REMOVE);

			break;
		  }

		} // for all spa

	} // if has BSDname

	return true;
}