void cmd_branch_dirty(fmd_hdl_t *hdl, cmd_branch_t *branch) { if (fmd_buf_size(hdl, NULL, branch->branch_bufname) != sizeof (cmd_branch_pers_t)) fmd_buf_destroy(hdl, NULL, branch->branch_bufname); /* No need to rewrite the FMRIs in the branch - they don't change */ fmd_buf_write(hdl, NULL, branch->branch_bufname, &branch->branch_pers, sizeof (cmd_branch_pers_t)); }
void * cmd_buf_read(fmd_hdl_t *hdl, fmd_case_t *cp, const char *bufname, size_t bufsz) { void *buf; size_t sz; if ((sz = fmd_buf_size(hdl, cp, bufname)) == 0) { (void) cmd_set_errno(ENOENT); return (NULL); } else if (sz != bufsz) { (void) cmd_set_errno(EINVAL); return (NULL); } buf = fmd_hdl_alloc(hdl, bufsz, FMD_SLEEP); fmd_buf_read(hdl, cp, bufname, buf, bufsz); return (buf); }
/* * Read back the persistent representation of an active case. */ static zfs_case_t * zfs_case_unserialize(fmd_hdl_t *hdl, fmd_case_t *cp) { zfs_case_t *zcp; size_t frulen; zcp = fmd_hdl_zalloc(hdl, sizeof (zfs_case_t), FMD_SLEEP); zcp->zc_case = cp; fmd_buf_read(hdl, cp, CASE_DATA, &zcp->zc_data, sizeof (zcp->zc_data)); if (zcp->zc_data.zc_version > CASE_DATA_VERSION_SERD) { fmd_hdl_free(hdl, zcp, sizeof (zfs_case_t)); return (NULL); } if ((frulen = fmd_buf_size(hdl, zcp->zc_case, CASE_FRU)) > 0) { zcp->zc_fru = fmd_hdl_alloc(hdl, frulen + 1, FMD_SLEEP); fmd_buf_read(hdl, zcp->zc_case, CASE_FRU, zcp->zc_fru, frulen); zcp->zc_fru[frulen] = '\0'; } /* * fmd_buf_read() will have already zeroed out the remainder of the * buffer, so we don't have to do anything special if the version * doesn't include the SERD engine name. */ if (zcp->zc_data.zc_has_remove_timer) zcp->zc_remove_timer = fmd_timer_install(hdl, zcp, NULL, zfs_remove_timeout); (void) uu_list_insert_before(zfs_cases, NULL, zcp); fmd_case_setspecific(hdl, cp, zcp); return (zcp); }
void * cmd_branch_restore(fmd_hdl_t *hdl, fmd_case_t *cp, cmd_case_ptr_t *ptr) { cmd_branch_t *branch; size_t branchsz; for (branch = cmd_list_next(&cmd.cmd_branches); branch != NULL; branch = cmd_list_next(branch)) { if (strcmp(branch->branch_bufname, ptr->ptr_name) == 0) break; } if (branch == NULL) { fmd_hdl_debug(hdl, "restoring branch from %s\n", ptr->ptr_name); if ((branchsz = fmd_buf_size(hdl, NULL, ptr->ptr_name)) == 0) { fmd_hdl_abort(hdl, "branch referenced by case %s does " "not exist in saved state\n", fmd_case_uuid(hdl, cp)); } else if (branchsz > CMD_BRANCH_MAXSIZE || branchsz < CMD_BRANCH_MINSIZE) { fmd_hdl_abort(hdl, "branch buffer referenced by case %s " "is out of bounds (is %u bytes, max %u, min %u)\n", fmd_case_uuid(hdl, cp), branchsz, CMD_BRANCH_MAXSIZE, CMD_BRANCH_MINSIZE); } if ((branch = cmd_buf_read(hdl, NULL, ptr->ptr_name, branchsz)) == NULL) { fmd_hdl_abort(hdl, "failed to read branch buf %s", ptr->ptr_name); } fmd_hdl_debug(hdl, "found %d in version field\n", branch->branch_version); switch (branch->branch_version) { case CMD_BRANCH_VERSION_0: branch = branch_wrapv0(hdl, (cmd_branch_pers_t *)branch, branchsz); break; default: fmd_hdl_abort(hdl, "unknown version (found %d) " "for branch state referenced by case %s.\n", branch->branch_version, fmd_case_uuid(hdl, cp)); break; } cmd_fmri_restore(hdl, &branch->branch_asru); if ((errno = nvlist_lookup_string(branch->branch_asru_nvl, FM_FMRI_MEM_UNUM, (char **)&branch->branch_unum)) != 0) fmd_hdl_abort(hdl, "failed to retrieve unum from asru"); cmd_list_append(&cmd.cmd_branches, branch); } switch (ptr->ptr_subtype) { case CMD_PTR_BRANCH_CASE: cmd_mem_case_restore(hdl, &branch->branch_case, cp, "branch", branch->branch_unum); break; default: fmd_hdl_abort(hdl, "invalid %s subtype %d\n", ptr->ptr_name, ptr->ptr_subtype); } return (branch); }