Index: lib/libdevctl/devctl.h =================================================================== --- lib/libdevctl/devctl.h +++ lib/libdevctl/devctl.h @@ -44,6 +44,7 @@ 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__ */ Index: lib/libdevctl/devctl.3 =================================================================== --- lib/libdevctl/devctl.3 +++ lib/libdevctl/devctl.3 @@ -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 @@ 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. Index: lib/libdevctl/devctl.c =================================================================== --- lib/libdevctl/devctl.c +++ lib/libdevctl/devctl.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "devctl.h" @@ -166,3 +167,43 @@ 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); +}