libdevctl: Add devctl_getpath
Helper routine to call the kernel to get a path to the named device. Different path enumeration methods (called locators) can be used for different path types depending on what the kernel implements. Sponsored by: Netflix Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D32746
This commit is contained in:
parent
38e942a345
commit
b01f409ffe
@ -36,6 +36,7 @@
|
||||
.Nm devctl_disable ,
|
||||
.Nm devctl_enable ,
|
||||
.Nm devctl_freeze ,
|
||||
.Nm devctl_getpath ,
|
||||
.Nm devctl_rescan ,
|
||||
.Nm devctl_reset ,
|
||||
.Nm devctl_resume ,
|
||||
@ -62,6 +63,8 @@
|
||||
.Ft int
|
||||
.Fn devctl_freeze "void"
|
||||
.Ft int
|
||||
.Fn devctl_getpath "const char *device" "const char *locator" "char **buffer"
|
||||
.Ft int
|
||||
.Fn devctl_rescan "const char *device"
|
||||
.Ft int
|
||||
.Fn devctl_reset "const char *device" "bool detach"
|
||||
@ -199,6 +202,18 @@ function rescans a bus device checking for devices that have been added or
|
||||
removed.
|
||||
.Pp
|
||||
The
|
||||
.Fn devctl_getpath
|
||||
retrieves the path to the
|
||||
.Fa device
|
||||
from the kernel using the
|
||||
.Fa locator
|
||||
method to construct the path.
|
||||
The
|
||||
.Fa buffer
|
||||
pointer is updated with an allocated buffer that must be freed with
|
||||
.Xr free .
|
||||
.Pp
|
||||
The
|
||||
.Fn devctl_freeze
|
||||
function freezes probe and attach processing initiated in response to
|
||||
drivers being loaded.
|
||||
|
@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/bus.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "devctl.h"
|
||||
|
||||
@ -166,3 +167,43 @@ devctl_reset(const char *device, bool detach)
|
||||
return (devctl_simple_request(DEV_RESET, device, detach ?
|
||||
DEVF_RESET_DETACH : 0));
|
||||
}
|
||||
|
||||
#define BUFLEN 1024
|
||||
|
||||
int
|
||||
devctl_getpath(const char *device, const char *locator, char **buffer)
|
||||
{
|
||||
struct devreq req;
|
||||
int serrno;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
if (strlcpy(req.dr_name, device, sizeof(req.dr_name)) >=
|
||||
sizeof(req.dr_name)) {
|
||||
errno = EINVAL;
|
||||
*buffer = NULL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Maybe do the request twice. Once to get the length, and then again to
|
||||
* get the string if BUFLEN bytes is insufficient.
|
||||
*/
|
||||
req.dr_flags = 0;
|
||||
req.dr_buffer.length = BUFLEN;
|
||||
again:
|
||||
req.dr_buffer.buffer = malloc(req.dr_buffer.length);
|
||||
strlcpy(req.dr_buffer.buffer, locator, req.dr_buffer.length);
|
||||
if (devctl_request(DEV_GET_PATH, &req) == 0) {
|
||||
*buffer = req.dr_buffer.buffer;
|
||||
return (0);
|
||||
}
|
||||
if (errno == ENAMETOOLONG && req.dr_buffer.length != BUFLEN) {
|
||||
free(req.dr_buffer.buffer);
|
||||
goto again;
|
||||
}
|
||||
serrno = errno;
|
||||
free(req.dr_buffer.buffer);
|
||||
errno = serrno;
|
||||
*buffer = NULL;
|
||||
return (-1);
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ int devctl_delete(const char *device, bool force);
|
||||
int devctl_freeze(void);
|
||||
int devctl_thaw(void);
|
||||
int devctl_reset(const char *device, bool detach);
|
||||
int devctl_getpath(const char *device, const char *locator, char **buffer);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !__DEVCTL_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user