#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/debug.h>
#include <sys/types.h>
#include <unistd.h>
#include <libintl.h>
#include <locale.h>
#include <string.h>
#include <libnvpair.h>
#include <libzfs.h>
#include <libzutil.h>
#include <libfstyp_module.h>
#include <errno.h>
struct fstyp_zfs {
int fd;
nvlist_t *config;
};
int fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle);
void fstyp_mod_fini(fstyp_mod_handle_t handle);
int fstyp_mod_ident(fstyp_mod_handle_t handle);
int fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp);
int
fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle)
{
struct fstyp_zfs *h;
if (offset != 0) {
return (FSTYP_ERR_OFFSET);
}
if ((h = calloc(1, sizeof (struct fstyp_zfs))) == NULL) {
return (FSTYP_ERR_NOMEM);
}
h->fd = fd;
*handle = (fstyp_mod_handle_t)h;
return (0);
}
void
fstyp_mod_fini(fstyp_mod_handle_t handle)
{
struct fstyp_zfs *h = (struct fstyp_zfs *)handle;
if (h->config != NULL) {
nvlist_free(h->config);
}
free(h);
}
int
fstyp_mod_ident(fstyp_mod_handle_t handle)
{
struct fstyp_zfs *h = (struct fstyp_zfs *)handle;
uint64_t state;
char *str;
uint64_t u64;
char buf[64];
int num_labels = 0;
if (zpool_read_label(h->fd, &h->config, &num_labels) != 0) {
VERIFY3S(errno, ==, ENOMEM);
return (FSTYP_ERR_NOMEM);
}
if (num_labels == 0)
return (FSTYP_ERR_NO_MATCH);
if (nvlist_lookup_uint64(h->config, ZPOOL_CONFIG_POOL_STATE,
&state) != 0 || state == POOL_STATE_DESTROYED) {
nvlist_free(h->config);
h->config = NULL;
return (FSTYP_ERR_NO_MATCH);
}
(void) nvlist_add_boolean_value(h->config, "gen_clean", B_TRUE);
if (nvlist_lookup_uint64(h->config, "guid", &u64) == 0) {
(void) snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)u64);
(void) nvlist_add_string(h->config, "gen_guid", buf);
}
if (nvlist_lookup_uint64(h->config, "version", &u64) == 0) {
(void) snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)u64);
(void) nvlist_add_string(h->config, "gen_version", buf);
}
if (nvlist_lookup_string(h->config, "name", &str) == 0) {
(void) nvlist_add_string(h->config, "gen_volume_label", str);
}
return (0);
}
int
fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp)
{
struct fstyp_zfs *h = (struct fstyp_zfs *)handle;
*attrp = h->config;
return (0);
}