Ejemplo n.º 1
0
/*
 * Open a handle to a disk.  This will fail if the device cannot be opened, or
 * if no suitable transport exists for communicating with the device.
 */
int
disk_status_open(disk_status_t *dsp, const char *path, int *error)
{
	ds_transport_t *t;
	int i;

	if ((dsp->ds_fd = open(path, O_RDWR)) < 0) {
		*error = EDS_CANT_OPEN;
		free(dsp);
		printf("Disk Module: DISK Open failed.\n");
		return (-1);
	}

	if ((dsp->ds_path = strdup(path)) == NULL) {
		*error = EDS_NOMEM;
		disk_status_close(dsp);
		return (-1);
	}

	for (i = 0; i < NTRANSPORTS; i++) {
		t = ds_transports[i];

		dsp->ds_transport = t;

		if ((dsp->ds_data = t->dt_open(dsp)) == NULL) {
			if (dsp->ds_error != EDS_NO_TRANSPORT) {
				*error = dsp->ds_error;
				disk_status_close(dsp);
				return (-1);
			}
		} else {
			dsp->ds_error = 0;
			break;
		}
	}

	if (dsp->ds_error == EDS_NO_TRANSPORT) {
		*error = dsp->ds_error;
		disk_status_close(dsp);
		return (-1);
	}

	return (0);
}
Ejemplo n.º 2
0
/*
 * Query the current disk status. If successful, the disk status is returned
 * as an nvlist consisting of at least the following members:
 *
 *	protocol	string		Supported protocol (currently "scsi")
 *
 *	status		nvlist		Arbitrary protocol-specific information
 *					about the current state of the disk.
 *
 *	faults		nvlist		A list of supported faults. Each
 *					element of this list is a boolean value.
 *					An element's existence indicates that
 *					the drive supports detecting this fault,
 *					and the value indicates the current
 *					state of the fault.
 *
 *	<fault-name>	nvlist		For each fault named in 'faults', a
 *					nvlist describing protocol-specific
 *					attributes of the fault.
 *
 * This method relies on the libdiskstatus library to query this information.
 */
static int
disk_status(topo_mod_t *mod, tnode_t *nodep, topo_version_t vers,
    nvlist_t *in_nvl, nvlist_t **out_nvl)
{
	disk_status_t	*dsp;
	char		*devpath, *fullpath;
	size_t		pathlen;
	nvlist_t	*status;
	int		err;

	*out_nvl = NULL;

	if (vers != TOPO_METH_DISK_STATUS_VERSION)
		return (topo_mod_seterrno(mod, EMOD_VER_NEW));

	/*
	 * If the caller specifies the "path" parameter, then this indicates
	 * that we should use this instead of deriving it from the topo node
	 * itself.
	 */
	if (nvlist_lookup_string(in_nvl, "path", &fullpath) == 0) {
		devpath = NULL;
	} else {
		/*
		 * Get the /devices path and attempt to open the disk status
		 * handle.
		 */
		if (topo_prop_get_string(nodep, TOPO_PGROUP_IO,
		    TOPO_IO_DEV_PATH, &devpath, &err) != 0)
			return (topo_mod_seterrno(mod, EMOD_METHOD_NOTSUP));

		/*
		 * Note that sizeof(string) includes the terminating NULL byte
		 */
		pathlen = strlen(devpath) + sizeof ("/devices") +
		    sizeof (PHYS_EXTN) - 1;

		if ((fullpath = topo_mod_alloc(mod, pathlen)) == NULL)
			return (topo_mod_seterrno(mod, EMOD_NOMEM));

		(void) snprintf(fullpath, pathlen, "/devices%s%s", devpath,
		    PHYS_EXTN);

		topo_mod_strfree(mod, devpath);
	}

	if ((dsp = disk_status_open(fullpath, &err)) == NULL) {
		if (devpath)
			topo_mod_free(mod, fullpath, pathlen);
		return (topo_mod_seterrno(mod, err == EDS_NOMEM ?
		    EMOD_NOMEM : EMOD_METHOD_NOTSUP));
	}

	if (devpath)
		topo_mod_free(mod, fullpath, pathlen);

	if ((status = disk_status_get(dsp)) == NULL) {
		err = (disk_status_errno(dsp) == EDS_NOMEM ?
		    EMOD_NOMEM : EMOD_METHOD_NOTSUP);
		disk_status_close(dsp);
		return (topo_mod_seterrno(mod, err));
	}

	*out_nvl = status;
	disk_status_close(dsp);
	return (0);
}