#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mdb_modapi.h>
#include <sys/smbios_impl.h>
#include <unistd.h>
extern char *strerror(int);
static int
smbios_mdb_write(const char *path, uintptr_t addr)
{
smbios_hdl_t shp, *hdl;
void *buf;
int err, fd = -1;
int ret = DCMD_ERR;
if (mdb_vread(&shp, sizeof (shp), addr) != sizeof (shp)) {
mdb_warn("failed to read smbios_hdl_t at %p", addr);
return (DCMD_ERR);
}
buf = mdb_alloc(shp.sh_buflen, UM_NOSLEEP | UM_GC);
if (buf == NULL) {
mdb_warn("failed to allocate %zu bytes for the smbios "
"data buffer", shp.sh_buflen);
return (DCMD_ERR);
}
if (mdb_vread(buf, shp.sh_buflen, (uintptr_t)shp.sh_buf) !=
shp.sh_buflen) {
mdb_warn("failed to copy smbios data at %p", shp.sh_buf);
return (DCMD_ERR);
}
hdl = smbios_bufopen(&shp.sh_ent, buf, shp.sh_buflen, SMB_VERSION, 0,
&err);
if (hdl == NULL) {
mdb_warn("failed to load smbios data: %s\n",
smbios_errmsg(err));
return (DCMD_ERR);
}
if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
mdb_warn("failed to open output file %s: %s\n", path,
strerror(errno));
goto out;
}
if (smbios_write(hdl, fd) != 0) {
mdb_warn("failed to write smbios data to %s: %s\n", path,
smbios_errmsg(smbios_errno(hdl)));
ret = DCMD_ERR;
} else {
ret = DCMD_OK;
}
out:
if (fd != -1) {
(void) close(fd);
}
smbios_close(hdl);
return (ret);
}
static int
smbios_mdb_smbios(uintptr_t addr, uint_t flags, int argc,
const mdb_arg_t *argv)
{
const char *wpath = NULL;
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("missing required smbios_hdl_t\n");
return (DCMD_USAGE);
}
if (mdb_getopts(argc, argv, 'w', MDB_OPT_STR, &wpath, NULL) != argc) {
return (DCMD_USAGE);
}
if (wpath != NULL) {
return (smbios_mdb_write(wpath, addr));
}
return (DCMD_USAGE);
}
static void
smbios_mdb_help(void)
{
mdb_printf("Given a pointer to an smbios_hdl_t take the following "
"actions:\n\n"
"\t-w path\t\tWrite SMBIOS data out to path\n");
}
static const mdb_dcmd_t smbios_dcmds[] = {
{ "smbios", ":[-w path]", "Manipulate an smbios handle",
smbios_mdb_smbios, smbios_mdb_help },
{ NULL }
};
static const mdb_modinfo_t smbios_modinfo = {
MDB_API_VERSION, smbios_dcmds, NULL
};
const mdb_modinfo_t *
_mdb_init(void)
{
return (&smbios_modinfo);
}