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_disable ,
|
||||||
.Nm devctl_enable ,
|
.Nm devctl_enable ,
|
||||||
.Nm devctl_freeze ,
|
.Nm devctl_freeze ,
|
||||||
|
.Nm devctl_getpath ,
|
||||||
.Nm devctl_rescan ,
|
.Nm devctl_rescan ,
|
||||||
.Nm devctl_reset ,
|
.Nm devctl_reset ,
|
||||||
.Nm devctl_resume ,
|
.Nm devctl_resume ,
|
||||||
@ -62,6 +63,8 @@
|
|||||||
.Ft int
|
.Ft int
|
||||||
.Fn devctl_freeze "void"
|
.Fn devctl_freeze "void"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn devctl_getpath "const char *device" "const char *locator" "char **buffer"
|
||||||
|
.Ft int
|
||||||
.Fn devctl_rescan "const char *device"
|
.Fn devctl_rescan "const char *device"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn devctl_reset "const char *device" "bool detach"
|
.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.
|
removed.
|
||||||
.Pp
|
.Pp
|
||||||
The
|
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
|
.Fn devctl_freeze
|
||||||
function freezes probe and attach processing initiated in response to
|
function freezes probe and attach processing initiated in response to
|
||||||
drivers being loaded.
|
drivers being loaded.
|
||||||
|
@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "devctl.h"
|
#include "devctl.h"
|
||||||
|
|
||||||
@ -166,3 +167,43 @@ devctl_reset(const char *device, bool detach)
|
|||||||
return (devctl_simple_request(DEV_RESET, device, detach ?
|
return (devctl_simple_request(DEV_RESET, device, detach ?
|
||||||
DEVF_RESET_DETACH : 0));
|
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_freeze(void);
|
||||||
int devctl_thaw(void);
|
int devctl_thaw(void);
|
||||||
int devctl_reset(const char *device, bool detach);
|
int devctl_reset(const char *device, bool detach);
|
||||||
|
int devctl_getpath(const char *device, const char *locator, char **buffer);
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
#endif /* !__DEVCTL_H__ */
|
#endif /* !__DEVCTL_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user