fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi/*
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi * This file and its contents are supplied under the terms of the
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0.
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi * You may only use this file in accordance with the terms of version
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi * 1.0 of the CDDL.
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi *
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi * A full copy of the text of the CDDL should have accompanied this
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi * source. A copy of the CDDL is also available via the Internet at
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi * http://www.illumos.org/license/CDDL.
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi */
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi/*
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi * Copyright (c) 2012 Joyent, Inc. All rights reserved.
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi * Use is subject to license terms.
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi */
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <sys/types.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <stdio.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <fcntl.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <errno.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <string.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <strings.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <stdlib.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <unistd.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <stdarg.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <libipd.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi#include <sys/ipd.h>
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi__thread ipd_errno_t ipd_errno = 0;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi__thread char ipd_errmsg[512];
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchistruct ipd_stat {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi uint_t is_nzones;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi zoneid_t *is_zoneids;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi struct ipd_config *is_configs;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi};
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchistatic ipd_errno_t
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchixlate_errno(int e)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi{
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi switch (e) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case 0:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (EIPD_NOERROR);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case ENOMEM:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EAGAIN:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (EIPD_NOMEM);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case ERANGE:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (EIPD_RANGE);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EPERM:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (EIPD_PERM);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EFAULT:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (EIPD_FAULT);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case ENOTTY:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (EIPD_INTERNAL);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi default:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (EIPD_UNKNOWN);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi}
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiconst char *
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiipd_strerror(ipd_errno_t e)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi{
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi switch (e) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EIPD_NOERROR:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return ("no error");
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EIPD_NOMEM:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return ("out of memory");
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EIPD_ZC_NOENT:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return ("zone does not exist or is not using ipd");
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EIPD_RANGE:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return ("argument out of range");
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EIPD_PERM:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return ("permission denied");
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EIPD_FAULT:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return ("bad pointer");
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EIPD_INTERNAL:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return ("internal library error");
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi case EIPD_UNKNOWN:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi default:
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return ("unknown error");
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi}
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchistatic int
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiipd_set_errno(ipd_errno_t e, const char *fmt, ...)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi{
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi va_list ap;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipd_errno = e;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (fmt != NULL) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi va_start(ap, fmt);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi (void) vsnprintf(ipd_errmsg, sizeof (ipd_errmsg), fmt, ap);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi va_end(ap);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi } else {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi (void) strlcpy(ipd_errmsg,
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipd_strerror(e), sizeof (ipd_errmsg));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (-1);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi}
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiint
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiipd_open(const char *path)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi{
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi int fd;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (path == NULL)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi path = IPD_DEV_PATH;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi fd = open(path, O_RDWR);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (fd < 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(xlate_errno(errno),
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi "unable to open %s: %s", path, strerror(errno)));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (fd);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi}
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiint
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiipd_close(int fd)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi{
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi (void) close(fd);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (0);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi}
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiint
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiipd_status_read(int fd, ipd_stathdl_t *ispp)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi{
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi struct ipd_stat *isp = NULL;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipd_ioc_list_t ipil;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi uint_t rzones;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi uint_t i;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi bzero(&ipil, sizeof (ipil));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (ioctl(fd, IPDIOC_LIST, &ipil) != 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(xlate_errno(errno),
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi "unable to retrieve ipd zone list: %s", strerror(errno)));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi for (;;) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if ((rzones = ipil.ipil_nzones) == 0)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi break;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipil.ipil_info =
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi malloc(sizeof (ipd_ioc_info_t) * ipil.ipil_nzones);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (ipil.ipil_info == NULL)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(EIPD_NOMEM, NULL));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (ioctl(fd, IPDIOC_LIST, &ipil) != 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(ipil.ipil_info);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(xlate_errno(errno),
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi "unable to retrieve ipd zone list: %s",
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi strerror(errno)));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (ipil.ipil_nzones <= rzones)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi break;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(ipil.ipil_info);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if ((isp = malloc(sizeof (struct ipd_stat))) == NULL) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(ipil.ipil_info);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(EIPD_NOMEM, NULL));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi isp->is_nzones = ipil.ipil_nzones;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (isp->is_nzones == 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi isp->is_zoneids = NULL;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi isp->is_configs = NULL;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi *ispp = isp;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (0);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi isp->is_zoneids = malloc(sizeof (zoneid_t) * ipil.ipil_nzones);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (isp->is_zoneids == NULL) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(ipil.ipil_info);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(isp);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(EIPD_NOMEM, NULL));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi isp->is_configs = malloc(sizeof (struct ipd_config) * ipil.ipil_nzones);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (isp->is_configs == NULL) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(ipil.ipil_info);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(isp->is_zoneids);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(isp);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(EIPD_NOMEM, NULL));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi for (i = 0; i < isp->is_nzones; i++) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi isp->is_zoneids[i] = ipil.ipil_info[i].ipii_zoneid;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi isp->is_configs[i].ic_corrupt = ipil.ipil_info[i].ipii_corrupt;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi isp->is_configs[i].ic_drop = ipil.ipil_info[i].ipii_drop;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi isp->is_configs[i].ic_delay = ipil.ipil_info[i].ipii_delay;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi isp->is_configs[i].ic_mask =
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ((!!isp->is_configs[i].ic_corrupt) * IPDM_CORRUPT) |
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ((!!isp->is_configs[i].ic_drop) * IPDM_DROP) |
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ((!!isp->is_configs[i].ic_delay) * IPDM_DELAY);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi *ispp = isp;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (0);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi}
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchivoid
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiipd_status_foreach_zone(const ipd_stathdl_t hdl, ipd_status_cb_f f, void *arg)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi{
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi const struct ipd_stat *isp = hdl;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi uint_t i;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi for (i = 0; i < isp->is_nzones; i++)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi f(isp->is_zoneids[i], &isp->is_configs[i], arg);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi}
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiint
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiipd_status_get_config(const ipd_stathdl_t hdl, zoneid_t z, ipd_config_t **icpp)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi{
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi const struct ipd_stat *isp = hdl;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi uint_t i;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi for (i = 0; i < isp->is_nzones; i++) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (isp->is_zoneids[i] == z) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi *icpp = &isp->is_configs[i];
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (0);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(EIPD_ZC_NOENT,
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi "zone %d does not exist or has no ipd configuration", z));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi}
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchivoid
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiipd_status_free(ipd_stathdl_t hdl)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi{
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi struct ipd_stat *isp = hdl;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (isp != NULL) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(isp->is_zoneids);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(isp->is_configs);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi free(isp);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi}
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiint
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchiipd_ctl(int fd, zoneid_t z, const ipd_config_t *icp)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi{
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipd_ioc_perturb_t ipip;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi bzero(&ipip, sizeof (ipd_ioc_perturb_t));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_zoneid = z;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (icp->ic_mask & IPDM_CORRUPT) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (icp->ic_corrupt == 0)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_arg |= IPD_CORRUPT;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (icp->ic_mask & IPDM_DELAY) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (icp->ic_delay == 0)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_arg |= IPD_DELAY;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (icp->ic_mask & IPDM_DROP) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (icp->ic_drop == 0)
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_arg |= IPD_DROP;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (ipip.ipip_arg != 0 && ioctl(fd, IPDIOC_REMOVE, &ipip) != 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(xlate_errno(errno),
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi "unable to remove cleared ipd settings: %s",
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi strerror(errno)));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if ((icp->ic_mask & IPDM_CORRUPT) && icp->ic_corrupt != 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_zoneid = z;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_arg = icp->ic_corrupt;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (ioctl(fd, IPDIOC_CORRUPT, &ipip) != 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(xlate_errno(errno),
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi "unable to set corruption rate to %d: %s",
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_arg, strerror(errno)));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if ((icp->ic_mask & IPDM_DELAY) && icp->ic_delay != 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_zoneid = z;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_arg = icp->ic_delay;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (ioctl(fd, IPDIOC_DELAY, &ipip) != 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(xlate_errno(errno),
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi "unable to set delay time to %d: %s",
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_arg, strerror(errno)));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if ((icp->ic_mask & IPDM_DROP) && icp->ic_drop != 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_zoneid = z;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_arg = icp->ic_drop;
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi if (ioctl(fd, IPDIOC_DROP, &ipip) != 0) {
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (ipd_set_errno(xlate_errno(errno),
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi "unable to set drop probability to %d: %s",
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi ipip.ipip_arg, strerror(errno)));
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi }
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi return (0);
fe77cc0407fb667ddc04e1a8f2e203bb7b9c80e1Robert Mustacchi}