Mercurial > illumos > illumos-gate
changeset 11170:349270d482cf
6854201 NDMP needs to include user and group quotas in backup stream
author | Reza Sabdar <Reza.Sabdar@Sun.COM> |
---|---|
date | Mon, 23 Nov 2009 16:04:12 -0800 |
parents | d46461938be8 |
children | 5f22130fc712 |
files | usr/src/cmd/ndmpd/include/tlm.h usr/src/cmd/ndmpd/ndmp/ndmpd_tar3.c usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c usr/src/lib/libndmp/common/libndmp.h |
diffstat | 5 files changed, 365 insertions(+), 76 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/ndmpd/include/tlm.h Mon Nov 23 14:57:01 2009 -0800 +++ b/usr/src/cmd/ndmpd/include/tlm.h Mon Nov 23 16:04:12 2009 -0800 @@ -51,6 +51,8 @@ #include <sys/stat.h> #include <time.h> #include <sys/queue.h> +#include <sys/fs/zfs.h> +#include <libzfs.h> #define IS_SET(f, m) (((f) & (m)) != 0) @@ -468,23 +470,77 @@ */ #define ZFS_MAX_PROPS 100 #define ZFS_META_MAGIC "ZFSMETA" +#define ZFS_META_MAGIC_EXT "ZFSMETA2" +/* Add new major/minor for header changes */ +typedef enum { + META_HDR_MAJOR_0, /* Original format */ + META_HDR_MAJOR_1, /* Extended format */ +} ndmp_metadata_header_major_t; + +#define META_HDR_MAJOR_VERSION META_HDR_MAJOR_1 + +typedef enum { + META_HDR_MINOR_0, +} ndmp_metadata_header_minor_t; + +#define META_HDR_MINOR_VERSION META_HDR_MINOR_0 + +/* To support older backups */ typedef struct ndmp_metadata_property { char mp_name[NAME_MAX]; char mp_value[NAME_MAX]; char mp_source[NAME_MAX]; } ndmp_metadata_property_t; +typedef struct ndmp_metadata_property_ext { + char mp_name[ZFS_MAXNAMELEN]; + char mp_value[ZFS_MAXPROPLEN]; + char mp_source[ZFS_MAXPROPLEN]; +} ndmp_metadata_property_ext_t; + +typedef struct ndmp_metadata_top_header { + char th_plname[100]; + uint_t th_plversion; + char th_magic[10]; + void *th_reserved_1; + int th_count; +} ndmp_metadata_top_header_t; + +/* Original metadata format */ typedef struct ndmp_metadata_header { - char nh_plname[100]; - uint_t nh_plversion; - char nh_magic[10]; - void *nh_handle; - int nh_count; + ndmp_metadata_top_header_t nh_hdr; char nh_dataset[NAME_MAX]; ndmp_metadata_property_t nh_property[1]; } ndmp_metadata_header_t; +/* Extended metadata format */ +typedef struct ndmp_metadata_header_ext { + ndmp_metadata_top_header_t nh_hdr; + char nh_dataset[ZFS_MAXNAMELEN]; + int32_t nh_total_bytes; + int32_t nh_major; + int32_t nh_minor; + ndmp_metadata_property_ext_t nh_property[1]; +} ndmp_metadata_header_ext_t; + +#define nh_plname nh_hdr.th_plname +#define nh_plversion nh_hdr.th_plversion +#define nh_magic nh_hdr.th_magic +#define nh_count nh_hdr.th_count + +typedef struct ndmp_metadata_handle { + void *ml_handle; + int32_t ml_quota_prop; + union { + ndmp_metadata_header_t *u_hdr; + ndmp_metadata_header_ext_t *u_xhdr; + } ml_hdr_u; +} ndmp_metadata_handle_t; + +#define ml_hdr ml_hdr_u.u_hdr +#define ml_xhdr ml_hdr_u.u_xhdr + /* * Node in struct hardlink_q *
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_tar3.c Mon Nov 23 14:57:01 2009 -0800 +++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_tar3.c Mon Nov 23 16:04:12 2009 -0800 @@ -2453,9 +2453,10 @@ nctx.nc_plversion = ndmp_pl->np_plversion; nctx.nc_plname = ndmpd_get_prop(NDMP_PLUGIN_PATH); nctx.nc_cmds = cmds; + nctx.nc_params = params; if ((err = ndmp_pl->np_pre_backup(ndmp_pl, &nctx, nlp->nlp_backup_path)) != 0) { - NDMP_LOG(LOG_DEBUG, "Pre-backup plug-in: %m"); + NDMP_LOG(LOG_ERR, "Pre-backup plug-in: %m"); goto backup_out; } } @@ -3223,13 +3224,14 @@ if (ndmp_pl != NULL && ndmp_pl->np_pre_restore != NULL) { nctx.nc_cmds = cmds; + nctx.nc_params = params; ep = (mem_ndmp_name_v3_t *)MOD_GETNAME(params, dar_index - 1); if ((err = ndmp_pl->np_pre_restore(ndmp_pl, &nctx, ep->nm3_opath, ep->nm3_dpath)) != 0) { - NDMP_LOG(LOG_DEBUG, "Pre-restore plug-in: %m"); + NDMP_LOG(LOG_ERR, "Pre-restore plug-in: %m"); cmds->tcs_command->tc_reader = TLM_STOP; ndmp_stop_local_reader(session, cmds); ndmp_wait_for_reader(cmds); @@ -3443,6 +3445,28 @@ return (0); } +/* + * Expands the format string and logs the resulting message to the + * remote DMA + */ +void +ndmp_log_dma(ndmp_context_t *nctx, ndmp_log_dma_type_t lt, const char *fmt, ...) +{ + va_list ap; + char buf[256]; + ndmpd_module_params_t *params; + + if (nctx == NULL || + (params = (ndmpd_module_params_t *)nctx->nc_params) == NULL) + return; + + va_start(ap, fmt); + (void) vsnprintf(buf, sizeof (buf), fmt, ap); + va_end(ap); + + MOD_LOGV3(params, (ndmp_log_type)lt, "%s", buf); +} + /* * ndmpd_rs_sar_tar_v3 @@ -3525,10 +3549,11 @@ if (ndmp_pl != NULL && ndmp_pl->np_pre_restore != NULL) { nctx.nc_cmds = cmds; + nctx.nc_params = params; if ((err = ndmp_plugin_pre_restore(&nctx, params, nlp->nlp_nfiles)) != 0) { - NDMP_LOG(LOG_DEBUG, "Pre-restore plug-in: %m"); + NDMP_LOG(LOG_ERR, "Pre-restore plug-in: %m"); cmds->tcs_command->tc_reader = TLM_STOP; ndmp_stop_local_reader(session, cmds); ndmp_wait_for_reader(cmds);
--- a/usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c Mon Nov 23 14:57:01 2009 -0800 +++ b/usr/src/cmd/ndmpd/tlm/tlm_backup_reader.c Mon Nov 23 16:04:12 2009 -0800 @@ -72,7 +72,7 @@ tlm_cmd_t *); extern libzfs_handle_t *zlibh; -extern mutex_t zlib_mtx; +extern mutex_t zlib_mtx; /* @@ -1180,30 +1180,41 @@ static int zfs_put_prop_cb(int prop, void *pp) { - ndmp_metadata_header_t *mhp; - ndmp_metadata_property_t *mpp; - char buf[ZFS_MAXNAMELEN]; - char sbuf[ZFS_MAXNAMELEN]; + ndmp_metadata_handle_t *mhd; + ndmp_metadata_header_ext_t *mhp; + ndmp_metadata_property_ext_t *mpp; + char vbuf[ZFS_MAXPROPLEN]; + char sbuf[ZFS_MAXPROPLEN]; zprop_source_t stype; char *sourcestr; if (pp == NULL) return (ZPROP_INVAL); - mhp = (ndmp_metadata_header_t *)pp; + mhd = (ndmp_metadata_handle_t *)pp; + mhp = mhd->ml_xhdr; + mpp = &mhp->nh_property[mhp->nh_count]; - if (zfs_prop_get(mhp->nh_handle, prop, buf, sizeof (buf), - &stype, sbuf, sizeof (sbuf), B_TRUE) != 0) + if (mhp->nh_count * sizeof (ndmp_metadata_property_ext_t) + + sizeof (ndmp_metadata_header_ext_t) > mhp->nh_total_bytes) + return (ZPROP_INVAL); + + if (zfs_prop_get(mhd->ml_handle, prop, vbuf, sizeof (vbuf), + &stype, sbuf, sizeof (sbuf), B_TRUE) != 0) { + mhp->nh_count++; return (ZPROP_CONT); + } - mpp = &mhp->nh_property[mhp->nh_count++]; - (void) strlcpy(mpp->mp_name, zfs_prop_to_name(prop), NAME_MAX); - (void) strlcpy(mpp->mp_value, buf, NAME_MAX); + (void) strlcpy(mpp->mp_name, zfs_prop_to_name(prop), ZFS_MAXNAMELEN); + (void) strlcpy(mpp->mp_value, vbuf, ZFS_MAXPROPLEN); switch (stype) { case ZPROP_SRC_NONE: sourcestr = "none"; break; + case ZPROP_SRC_RECEIVED: + sourcestr = "received"; + break; case ZPROP_SRC_LOCAL: sourcestr = mhp->nh_dataset; break; @@ -1217,11 +1228,103 @@ sourcestr = sbuf; break; } - (void) strlcpy(mpp->mp_source, sourcestr, NAME_MAX); + (void) strlcpy(mpp->mp_source, sourcestr, ZFS_MAXPROPLEN); + mhp->nh_count++; return (ZPROP_CONT); } +/* + * Callback to backup each ZFS user/group quota + */ +static int +zfs_put_quota_cb(void *pp, const char *domain, uid_t rid, uint64_t space) +{ + ndmp_metadata_handle_t *mhd; + ndmp_metadata_header_ext_t *mhp; + ndmp_metadata_property_ext_t *mpp; + char *typestr; + + if (pp == NULL) + return (ZPROP_INVAL); + + mhd = (ndmp_metadata_handle_t *)pp; + mhp = mhd->ml_xhdr; + mpp = &mhp->nh_property[mhp->nh_count]; + + if (mhp->nh_count * sizeof (ndmp_metadata_property_ext_t) + + sizeof (ndmp_metadata_header_ext_t) > mhp->nh_total_bytes) + return (ZPROP_INVAL); + + if (mhd->ml_quota_prop == ZFS_PROP_USERQUOTA) + typestr = "userquota"; + else + typestr = "groupquota"; + + if (domain == NULL || *domain == '\0') + (void) snprintf(mpp->mp_name, ZFS_MAXNAMELEN, "%s@%llu", + typestr, (longlong_t)rid); + else + (void) snprintf(mpp->mp_name, ZFS_MAXNAMELEN, "%s@%s-%llu", + typestr, domain, (longlong_t)rid); + (void) snprintf(mpp->mp_value, ZFS_MAXPROPLEN, "%llu", space); + (void) strlcpy(mpp->mp_source, mhp->nh_dataset, ZFS_MAXPROPLEN); + + mhp->nh_count++; + return (0); +} + +/* + * Callback to count each ZFS property + */ +/*ARGSUSED*/ +static int +zfs_count_prop_cb(int prop, void *pp) +{ + (*(int *)pp)++; + return (ZPROP_CONT); +} + +/* + * Callback to count each ZFS user/group quota + */ +/*ARGSUSED*/ +static int +zfs_count_quota_cb(void *pp, const char *domain, uid_t rid, uint64_t space) +{ + (*(int *)pp)++; + return (0); +} + +/* + * Count the number of ZFS properties and user/group quotas + */ +int +zfs_get_prop_counts(zfs_handle_t *zhp) +{ + int count = 0; + nvlist_t *uprops; + nvpair_t *elp; + + if (zhp == NULL) + return (0); + + (void) zprop_iter(zfs_count_prop_cb, &count, TRUE, TRUE, + ZFS_TYPE_VOLUME | ZFS_TYPE_DATASET); + + (void) zfs_userspace(zhp, ZFS_PROP_USERQUOTA, zfs_count_quota_cb, + &count); + (void) zfs_userspace(zhp, ZFS_PROP_GROUPQUOTA, zfs_count_quota_cb, + &count); + + uprops = zfs_get_user_props(zhp); + + elp = nvlist_next_nvpair(uprops, NULL); + for (; elp != NULL; elp = nvlist_next_nvpair(uprops, elp)) + count++; + + return (count); +} /* * Notifies ndmpd that the metadata associated with the given ZFS dataset @@ -1231,8 +1334,10 @@ ndmp_include_zfs(ndmp_context_t *nctx, const char *dataset) { tlm_commands_t *cmds; - ndmp_metadata_header_t *mhp; - ndmp_metadata_property_t *mpp; + ndmp_metadata_handle_t mhd; + ndmp_metadata_header_ext_t *mhp; + ndmp_metadata_property_ext_t *mpp; + zfs_handle_t *zhp; tlm_cmd_t *lcmd; long actual_size; nvlist_t *uprops, *ulist; @@ -1242,6 +1347,7 @@ char *wbuf, *pp, *tp; long size, lsize, sz; int align = RECORDSIZE - 1; + int pcount; if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL) return (-1); @@ -1250,35 +1356,46 @@ lcmd->tc_buffers == NULL) return (-1); - size = sizeof (ndmp_metadata_header_t) + - ZFS_MAX_PROPS * sizeof (ndmp_metadata_property_t); + (void) mutex_lock(&zlib_mtx); + if ((zhp = zfs_open(zlibh, dataset, ZFS_TYPE_DATASET)) == NULL) { + (void) mutex_unlock(&zlib_mtx); + return (-1); + } + + pcount = zfs_get_prop_counts(zhp); + size = sizeof (ndmp_metadata_header_ext_t) + + pcount * sizeof (ndmp_metadata_property_ext_t); + size += align; size &= ~align; - if ((mhp = malloc(size)) == NULL) + if ((mhp = malloc(size)) == NULL) { + zfs_close(zhp); + (void) mutex_unlock(&zlib_mtx); return (-1); + } + (void) memset(mhp, 0, size); + mhd.ml_handle = zhp; + mhd.ml_xhdr = mhp; + mhp->nh_total_bytes = size; + mhp->nh_major = META_HDR_MAJOR_VERSION; + mhp->nh_minor = META_HDR_MINOR_VERSION; mhp->nh_plversion = nctx->nc_plversion; + (void) strlcpy(mhp->nh_plname, nctx->nc_plname, sizeof (mhp->nh_plname)); - (void) strlcpy(mhp->nh_magic, ZFS_META_MAGIC, sizeof (mhp->nh_magic)); + (void) strlcpy(mhp->nh_magic, ZFS_META_MAGIC_EXT, + sizeof (mhp->nh_magic)); (void) strlcpy(mhp->nh_dataset, dataset, sizeof (mhp->nh_dataset)); - (void) mutex_lock(&zlib_mtx); - if ((mhp->nh_handle = zfs_open(zlibh, dataset, - ZFS_TYPE_DATASET)) == NULL) { - (void) mutex_unlock(&zlib_mtx); - free(mhp); - return (ZPROP_INVAL); - } - /* Get all the ZFS properties */ - (void) zprop_iter(zfs_put_prop_cb, mhp, TRUE, TRUE, + (void) zprop_iter(zfs_put_prop_cb, &mhd, TRUE, TRUE, ZFS_TYPE_VOLUME | ZFS_TYPE_DATASET); /* Get user properties */ - uprops = zfs_get_user_props(mhp->nh_handle); + uprops = zfs_get_user_props(mhd.ml_handle); elp = nvlist_next_nvpair(uprops, NULL); @@ -1287,21 +1404,29 @@ if (nvpair_value_nvlist(elp, &ulist) != 0 || nvlist_lookup_string(ulist, ZPROP_VALUE, &sval) != 0 || nvlist_lookup_string(ulist, ZPROP_SOURCE, &ssrc) != 0) { - zfs_close(mhp->nh_handle); + zfs_close(mhd.ml_handle); (void) mutex_unlock(&zlib_mtx); free(mhp); return (-1); } if ((pname = nvpair_name(elp)) != NULL) - (void) strlcpy(mpp->mp_name, pname, NAME_MAX); + (void) strlcpy(mpp->mp_name, pname, ZFS_MAXNAMELEN); - (void) strlcpy(mpp->mp_value, sval, NAME_MAX); - (void) strlcpy(mpp->mp_source, ssrc, NAME_MAX); + (void) strlcpy(mpp->mp_value, sval, ZFS_MAXPROPLEN); + (void) strlcpy(mpp->mp_source, ssrc, ZFS_MAXPROPLEN); mhp->nh_count++; elp = nvlist_next_nvpair(uprops, elp); } - zfs_close(mhp->nh_handle); + mhd.ml_quota_prop = ZFS_PROP_USERQUOTA; + (void) zfs_userspace(mhd.ml_handle, ZFS_PROP_USERQUOTA, + zfs_put_quota_cb, &mhd); + mhd.ml_quota_prop = ZFS_PROP_GROUPQUOTA; + (void) zfs_userspace(mhd.ml_handle, ZFS_PROP_GROUPQUOTA, + zfs_put_quota_cb, &mhd); + mhp->nh_count = pcount; + + zfs_close(mhd.ml_handle); (void) mutex_unlock(&zlib_mtx); if ((wbuf = get_write_buffer(size, &actual_size, TRUE, @@ -1316,7 +1441,7 @@ while (sz < size && ((tp = get_write_buffer(size - sz, &lsize, TRUE, lcmd))) != NULL) { - (void) memcpy(tp, pp, size - sz); + (void) memcpy(tp, pp, lsize); sz += lsize; pp += lsize; }
--- a/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c Mon Nov 23 14:57:01 2009 -0800 +++ b/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c Mon Nov 23 16:04:12 2009 -0800 @@ -2160,14 +2160,14 @@ { tlm_commands_t *cmds; ndmp_metadata_header_t *mhp; + ndmp_metadata_header_ext_t *mhpx; ndmp_metadata_property_t *mpp; + ndmp_metadata_property_ext_t *mppx; tlm_cmd_t *lcmd; int actual_size; nvlist_t *nvl; - nvlist_t *nvl_head; nvlist_t *valp; nvpair_t *nvp = NULL; - nvpair_t *nvph = NULL; char plname[100]; char *mhbuf, *pp, *tp; int rv, i; @@ -2182,15 +2182,12 @@ lcmd->tc_buffers == NULL) return (-1); + /* Default minimum bytes needed */ size = sizeof (ndmp_metadata_header_t) + ZFS_MAX_PROPS * sizeof (ndmp_metadata_property_t); size += align; size &= ~align; - /* For nvlist cleanup */ - if (nvlist_alloc(&nvl_head, NV_UNIQUE_NAME, 0) != 0) - return (-1); - if ((mhbuf = malloc(size)) == NULL) return (-1); @@ -2200,13 +2197,29 @@ pp = mhbuf; if (strncmp(mhp->nh_magic, ZFS_META_MAGIC, + sizeof (mhp->nh_magic)) != 0 && + strncmp(mhp->nh_magic, ZFS_META_MAGIC_EXT, sizeof (mhp->nh_magic)) != 0) { /* No more metadata */ tlm_unget_read_buffer(lcmd->tc_buffers, actual_size); - nvlist_free(nvl_head); + free(mhbuf); return (0); } + if (strncmp(mhp->nh_magic, ZFS_META_MAGIC_EXT, + sizeof (mhp->nh_magic)) == 0) { + mhpx = (ndmp_metadata_header_ext_t *)mhp; + if (mhpx->nh_total_bytes > size) { + if ((pp = realloc(mhbuf, mhpx->nh_total_bytes)) + == NULL) { + free(mhbuf); + return (-1); + } + mhbuf = pp; + } + size = mhpx->nh_total_bytes; + } + (void) memcpy(pp, (char *)mhp, (actual_size < size) ? actual_size : size); pp += (actual_size < size) ? actual_size : size; @@ -2215,55 +2228,116 @@ while (sz < size && ((tp = get_read_buffer(size - sz, &rv, &lsize, lcmd))) != NULL) { - (void) memcpy(pp, tp, size - sz); + (void) memcpy(pp, tp, lsize); sz += lsize; pp += lsize; } if (sz > size) { tlm_unget_read_buffer(lcmd->tc_buffers, sz - size); } + /* LINTED improper alignment */ mhp = (ndmp_metadata_header_t *)mhbuf; - nctx->nc_plversion = mhp->nh_plversion; - (void) strlcpy(plname, mhp->nh_plname, sizeof (plname)); + nvl = NULL; + if (strncmp(mhp->nh_magic, ZFS_META_MAGIC_EXT, + sizeof (mhp->nh_magic)) == 0) { + /* New metadata format */ + /* LINTED improper alignment */ + mhpx = (ndmp_metadata_header_ext_t *)mhbuf; - if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) - goto nvlist_err; + if (mhpx->nh_major > META_HDR_MAJOR_VERSION) { + /* Major header mismatch */ + NDMP_LOG(LOG_ERR, "metadata header mismatch", + "M%d != M%d", mhpx->nh_major, + META_HDR_MAJOR_VERSION); + free(mhbuf); + return (-1); + } + if (mhpx->nh_major == META_HDR_MAJOR_VERSION && + mhpx->nh_minor > META_HDR_MINOR_VERSION) { + /* Minor header mismatch */ + NDMP_LOG(LOG_ERR, "Warning:" + "metadata header mismatch m%d != m%d", + mhpx->nh_minor, + META_HDR_MINOR_VERSION); + continue; + } + + nctx->nc_plversion = mhpx->nh_plversion; + (void) strlcpy(plname, mhpx->nh_plname, + sizeof (plname)); + + if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) + goto nvlist_err; - mpp = &mhp->nh_property[0]; - for (i = 0; i < mhp->nh_count && mpp; i++) { - if (nvlist_alloc(&valp, NV_UNIQUE_NAME, 0) != 0 || - nvlist_add_string(valp, "value", - mpp->mp_value) != 0 || - nvlist_add_string(valp, "source", - mpp->mp_source) != 0 || - nvlist_add_nvlist(nvl, mpp->mp_name, valp) != 0) + mppx = &mhpx->nh_property[0]; + for (i = 0; i < mhpx->nh_count && mppx; i++, mppx++) { + if (!*mppx->mp_name) + continue; + valp = NULL; + if (nvlist_alloc(&valp, + NV_UNIQUE_NAME, 0) != 0 || + nvlist_add_string(valp, "value", + mppx->mp_value) != 0 || + nvlist_add_string(valp, "source", + mppx->mp_source) != 0 || + nvlist_add_nvlist(nvl, mppx->mp_name, + valp) != 0) { + nvlist_free(valp); + goto nvlist_err; + } + nvlist_free(valp); + } + } else { + nctx->nc_plversion = mhp->nh_plversion; + (void) strlcpy(plname, mhp->nh_plname, + sizeof (plname)); + + if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) goto nvlist_err; - mpp++; + + mpp = &mhp->nh_property[0]; + for (i = 0; i < mhp->nh_count && mpp; i++, mpp++) { + if (!*mpp->mp_name) + continue; + valp = NULL; + if (nvlist_alloc(&valp, + NV_UNIQUE_NAME, 0) != 0 || + nvlist_add_string(valp, "value", + mpp->mp_value) != 0 || + nvlist_add_string(valp, "source", + mpp->mp_source) != 0 || + nvlist_add_nvlist(nvl, mpp->mp_name, + valp) != 0) { + nvlist_free(valp); + goto nvlist_err; + } + nvlist_free(valp); + } } if (np_restore_property(nvl, ptr) != 0) goto nvlist_err; - (void) nvlist_add_nvlist(nvl_head, "_", nvl); - } - free(mhbuf); - - nvlist_free(nvl_head); - return (0); - -nvlist_err: - free(mhbuf); - while ((nvph = nvlist_next_nvpair(nvl_head, nvph)) != NULL && - nvpair_value_nvlist(nvph, &nvl) == 0) { while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL && nvpair_value_nvlist(nvp, &valp) == 0) { nvlist_free(valp); } nvlist_free(nvl); } - nvlist_free(nvl_head); + + free(mhbuf); + return (0); + +nvlist_err: + free(mhbuf); + + while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL && + nvpair_value_nvlist(nvp, &valp) == 0) { + nvlist_free(valp); + } + nvlist_free(nvl); return (-1); }
--- a/usr/src/lib/libndmp/common/libndmp.h Mon Nov 23 14:57:01 2009 -0800 +++ b/usr/src/lib/libndmp/common/libndmp.h Mon Nov 23 16:04:12 2009 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -66,6 +66,7 @@ uint_t nc_plversion; void *nc_pldata; void *nc_cmds; + void *nc_params; } ndmp_context_t; typedef struct ndmp_plugin { @@ -84,6 +85,13 @@ int); } ndmp_plugin_t; +typedef enum ndmp_log_dma_type { + NDMP_LOGD_NORMAL = 0, + NDMP_LOGD_DEBUG = 1, + NDMP_LOGD_ERROR = 2, + NDMP_LOGD_WARNING = 3 +} ndmp_log_dma_type_t; + /* libndmp error codes */ #define ENDMP_BASE 2000 enum { @@ -360,6 +368,7 @@ extern uint_t ndmp_context_get_version(ndmp_context_t *); extern void ndmp_context_set_specific(ndmp_context_t *, void *); extern void *ndmp_context_get_specific(ndmp_context_t *); +void ndmp_log_dma(ndmp_context_t *, ndmp_log_dma_type_t, const char *, ...); #ifdef __cplusplus }