dlmgmt_db.c revision 6ba597c56d749c61b4f783157f63196d7b2445f0
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * CDDL HEADER START
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * The contents of this file are subject to the terms of the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Common Development and Distribution License (the "License").
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * You may not use this file except in compliance with the License.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * or http://www.opensolaris.org/os/licensing.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * See the License for the specific language governing permissions
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * and limitations under the License.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * When distributing Covered Code, include this CDDL HEADER in each
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If applicable, add the following below this CDDL HEADER, with the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * fields enclosed by brackets "[]" replaced with your own identifying
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * information: Portions Copyright [yyyy] [name of copyright owner]
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * CDDL HEADER END
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Use is subject to license terms.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <assert.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <ctype.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <errno.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <fcntl.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <stdio.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <stdlib.h>
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#include <string.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <strings.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <syslog.h>
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#include <zone.h>
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#include <sys/types.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <sys/stat.h>
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#include <stropts.h>
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#include <sys/conf.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <pthread.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <unistd.h>
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#include <wait.h>
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#include <libcontract.h>
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#include <sys/contract/process.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include "dlmgmt_impl.h"
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef enum dlmgmt_db_op {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz DLMGMT_DB_OP_WRITE,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz DLMGMT_DB_OP_DELETE,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz DLMGMT_DB_OP_READ
d62bc4badc1c1f1549c961cfb8b420e650e1272byz} dlmgmt_db_op_t;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef struct dlmgmt_db_req_s {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz struct dlmgmt_db_req_s *ls_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_db_op_t ls_op;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy char ls_link[MAXLINKNAMELEN];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz datalink_id_t ls_linkid;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zoneid_t ls_zoneid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint32_t ls_flags; /* Either DLMGMT_ACTIVE or */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* DLMGMT_PERSIST, not both. */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz} dlmgmt_db_req_t;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * List of pending db updates (e.g., because of a read-only filesystem).
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic dlmgmt_db_req_t *dlmgmt_db_req_head = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic dlmgmt_db_req_t *dlmgmt_db_req_tail = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * rewrite_needed is set to B_TRUE by process_link_line() if it encounters a
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * line with an old format. This will cause the file being read to be
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * re-written with the current format.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic boolean_t rewrite_needed;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int dlmgmt_db_update(dlmgmt_db_op_t, const char *,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_link_t *, uint32_t);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int dlmgmt_process_db_req(dlmgmt_db_req_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int dlmgmt_process_db_onereq(dlmgmt_db_req_t *, boolean_t);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void *dlmgmt_db_update_thread(void *);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic boolean_t process_link_line(char *, dlmgmt_link_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int process_db_write(dlmgmt_db_req_t *, FILE *, FILE *);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int process_db_read(dlmgmt_db_req_t *, FILE *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void generate_link_line(dlmgmt_link_t *, boolean_t, char *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define BUFLEN(lim, ptr) (((lim) > (ptr)) ? ((lim) - (ptr)) : 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define MAXLINELEN 1024
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roytypedef void db_walk_func_t(dlmgmt_link_t *);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Translator functions to go from dladm_datatype_t to character strings.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Each function takes a pointer to a buffer, the size of the buffer,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * the name of the attribute, and the value to be written. The functions
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * return the number of bytes written to the buffer. If the buffer is not big
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * enough to hold the string representing the value, then nothing is written
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * and 0 is returned.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef size_t write_func_t(char *, size_t, char *, void *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Translator functions to read from a NULL terminated string buffer into
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * something of the given DLADM_TYPE_*. The functions each return the number
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * of bytes read from the string buffer. If there is an error reading data
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * from the buffer, then 0 is returned. It is the caller's responsibility
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * to free the data allocated by these functions.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef size_t read_func_t(char *, void **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef struct translator_s {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz const char *type_name;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz write_func_t *write_func;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz read_func_t *read_func;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz} translator_t;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Translator functions, defined later but declared here so that
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * the translator table can be defined.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic write_func_t write_str, write_boolean, write_uint64;
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic read_func_t read_str, read_boolean, read_int64;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Translator table, indexed by dladm_datatype_t.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic translator_t translators[] = {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz { "string", write_str, read_str },
d62bc4badc1c1f1549c961cfb8b420e650e1272byz { "boolean", write_boolean, read_boolean },
d62bc4badc1c1f1549c961cfb8b420e650e1272byz { "int", write_uint64, read_int64 }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic size_t ntranslators = sizeof (translators) / sizeof (translator_t);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define LINK_PROPERTY_DELIMINATOR ";"
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define LINK_PROPERTY_TYPE_VALUE_SEP ","
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define BASE_PROPERTY_LENGTH(t, n) (strlen(translators[(t)].type_name) +\
d62bc4badc1c1f1549c961cfb8b420e650e1272byz strlen(LINK_PROPERTY_TYPE_VALUE_SEP) +\
d62bc4badc1c1f1549c961cfb8b420e650e1272byz strlen(LINK_PROPERTY_DELIMINATOR) +\
d62bc4badc1c1f1549c961cfb8b420e650e1272byz strlen((n)))
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define GENERATE_PROPERTY_STRING(buf, length, conv, name, type, val) \
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (snprintf((buf), (length), "%s=%s%s" conv "%s", (name), \
d62bc4badc1c1f1549c961cfb8b420e650e1272byz translators[(type)].type_name, \
d62bc4badc1c1f1549c961cfb8b420e650e1272byz LINK_PROPERTY_TYPE_VALUE_SEP, (val), LINK_PROPERTY_DELIMINATOR))
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Name of the cache file to keep the active <link name, linkid> mapping
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roychar cachefile[MAXPATHLEN];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define DLMGMT_PERSISTENT_DB_PATH "/etc/dladm/datalink.conf"
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define DLMGMT_MAKE_FILE_DB_PATH(buffer, persistent) \
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf((buffer), MAXPATHLEN, "%s", \
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (persistent) ? DLMGMT_PERSISTENT_DB_PATH : cachefile);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roytypedef struct zopen_arg {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy const char *zopen_modestr;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int *zopen_pipe;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int zopen_fd;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy} zopen_arg_t;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roytypedef struct zrename_arg {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy const char *zrename_newname;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy} zrename_arg_t;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roytypedef union zfoparg {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zopen_arg_t zfop_openarg;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zrename_arg_t zfop_renamearg;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy} zfoparg_t;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roytypedef struct zfcbarg {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy boolean_t zfarg_inglobalzone; /* is callback in global zone? */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zoneid_t zfarg_finglobalzone; /* is file in global zone? */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy const char *zfarg_filename;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfoparg_t *zfarg_oparg;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy} zfarg_t;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#define zfarg_openarg zfarg_oparg->zfop_openarg
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy#define zfarg_renamearg zfarg_oparg->zfop_renamearg
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/* zone file callback */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roytypedef int zfcb_t(zfarg_t *);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Execute an operation on filename relative to zoneid's zone root. If the
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * file is in the global zone, then the zfcb() callback will simply be called
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * directly. If the file is in a non-global zone, then zfcb() will be called
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * both from the global zone's context, and from the non-global zone's context
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * (from a fork()'ed child that has entered the non-global zone). This is
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * done to allow the callback to communicate with itself if needed (e.g. to
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * pass back the file descriptor of an opened file).
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_zfop(const char *filename, zoneid_t zoneid, zfcb_t *zfcb,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfoparg_t *zfoparg)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int ctfd;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int err;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy pid_t childpid;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy siginfo_t info;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfarg_t zfarg;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (zoneid != GLOBAL_ZONEID) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * We need to access a file that isn't in the global zone.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Accessing non-global zone files from the global zone is
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * unsafe (due to symlink attacks), we'll need to fork a child
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * that enters the zone in question and executes the callback
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * that will operate on the file.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy *
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Before we proceed with this zone tango, we need to create a
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * new process contract for the child, as required by
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * zone_enter().
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy errno = 0;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ctfd = open64("/system/contract/process/template", O_RDWR);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (ctfd == -1)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((err = ct_tmpl_set_critical(ctfd, 0)) != 0 ||
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (err = ct_tmpl_set_informative(ctfd, 0)) != 0 ||
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (err = ct_pr_tmpl_set_fatal(ctfd, CT_PR_EV_HWERR)) != 0 ||
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (err = ct_pr_tmpl_set_param(ctfd, CT_PR_PGRPONLY)) != 0 ||
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (err = ct_tmpl_activate(ctfd)) != 0) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (err);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy childpid = fork();
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) ct_tmpl_clear(ctfd);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) close(ctfd);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy switch (childpid) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy case -1:
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (err);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy case 0:
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Elevate our privileges as zone_enter() requires all
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * privileges.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((err = dlmgmt_elevate_privileges()) != 0)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy _exit(err);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (zone_enter(zoneid) == -1)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy _exit(errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((err = dlmgmt_drop_privileges()) != 0)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy _exit(err);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy break;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy default:
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (waitid(P_PID, childpid, &info, WEXITED) == -1)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (info.si_status != 0)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (info.si_status);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfarg.zfarg_inglobalzone = (zoneid == GLOBAL_ZONEID || childpid != 0);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfarg.zfarg_finglobalzone = (zoneid == GLOBAL_ZONEID);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfarg.zfarg_filename = filename;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfarg.zfarg_oparg = zfoparg;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = zfcb(&zfarg);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (!zfarg.zfarg_inglobalzone)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy _exit(err);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (err);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_zopen_cb(zfarg_t *zfarg)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy struct strrecvfd recvfd;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy boolean_t newfile = B_FALSE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy boolean_t inglobalzone = zfarg->zfarg_inglobalzone;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zoneid_t finglobalzone = zfarg->zfarg_finglobalzone;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy const char *filename = zfarg->zfarg_filename;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy const char *modestr = zfarg->zfarg_openarg.zopen_modestr;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int *p = zfarg->zfarg_openarg.zopen_pipe;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy struct stat statbuf;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int oflags;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy mode_t mode;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int fd = -1;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int err;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* We only ever open a file for reading or writing, not both. */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy oflags = (modestr[0] == 'r') ? O_RDONLY : O_WRONLY | O_CREAT | O_TRUNC;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy mode = (modestr[0] == 'r') ? 0 : S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* Open the file if we're in the same zone as the file. */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (inglobalzone == finglobalzone) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * First determine if we will be creating the file as part of
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * opening it. If so, then we'll need to ensure that it has
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * the proper ownership after having opened it.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (oflags & O_CREAT) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (stat(filename, &statbuf) == -1) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (errno == ENOENT)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy newfile = B_TRUE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy else
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((fd = open(filename, oflags, mode)) == -1)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (newfile) {
6ba597c56d749c61b4f783157f63196d7b2445f0Anurag S. Maskey if (chown(filename, UID_DLADM, GID_NETADM) == -1) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = errno;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) close(fd);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (err);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * If we're not in the global zone, send the file-descriptor back to
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * our parent in the global zone.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (!inglobalzone) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy assert(!finglobalzone);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy assert(fd != -1);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (ioctl(p[1], I_SENDFD, fd) == -1 ? errno : 0);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * At this point, we know we're in the global zone. If the file was
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * in a non-global zone, receive the file-descriptor from our child in
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * the non-global zone.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (!finglobalzone) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (ioctl(p[0], I_RECVFD, &recvfd) == -1)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy fd = recvfd.fd;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfarg->zfarg_openarg.zopen_fd = fd;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (0);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_zunlink_cb(zfarg_t *zfarg)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (zfarg->zfarg_inglobalzone != zfarg->zfarg_finglobalzone)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (0);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (unlink(zfarg->zfarg_filename) == 0 ? 0 : errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_zrename_cb(zfarg_t *zfarg)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (zfarg->zfarg_inglobalzone != zfarg->zfarg_finglobalzone)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (0);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (rename(zfarg->zfarg_filename,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfarg->zfarg_renamearg.zrename_newname) == 0 ? 0 : errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Same as fopen(3C), except that it opens the file relative to zoneid's zone
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * root.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic FILE *
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_zfopen(const char *filename, const char *modestr, zoneid_t zoneid,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int *err)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int p[2];
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfoparg_t zfoparg;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy FILE *fp = NULL;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (zoneid != GLOBAL_ZONEID && pipe(p) == -1) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy *err = errno;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (NULL);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfoparg.zfop_openarg.zopen_modestr = modestr;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfoparg.zfop_openarg.zopen_pipe = p;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy *err = dlmgmt_zfop(filename, zoneid, dlmgmt_zopen_cb, &zfoparg);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (zoneid != GLOBAL_ZONEID) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) close(p[0]);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) close(p[1]);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (*err == 0) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy fp = fdopen(zfoparg.zfop_openarg.zopen_fd, modestr);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (fp == NULL) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy *err = errno;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) close(zfoparg.zfop_openarg.zopen_fd);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (fp);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Same as rename(2), except that old and new are relative to zoneid's zone
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * root.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_zrename(const char *old, const char *new, zoneid_t zoneid)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfoparg_t zfoparg;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zfoparg.zfop_renamearg.zrename_newname = new;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (dlmgmt_zfop(old, zoneid, dlmgmt_zrename_cb, &zfoparg));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Same as unlink(2), except that filename is relative to zoneid's zone root.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_zunlink(const char *filename, zoneid_t zoneid)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (dlmgmt_zfop(filename, zoneid, dlmgmt_zunlink_cb, NULL));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic size_t
d62bc4badc1c1f1549c961cfb8b420e650e1272byzwrite_str(char *buffer, size_t buffer_length, char *name, void *value)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char *ptr = value;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz size_t data_length = strnlen(ptr, buffer_length);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Strings are assumed to be NULL terminated. In order to fit in
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * the buffer, the string's length must be less then buffer_length.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If the value is empty, there's no point in writing it, in fact,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * we shouldn't even see that case.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (data_length + BASE_PROPERTY_LENGTH(DLADM_TYPE_STR, name) ==
d62bc4badc1c1f1549c961cfb8b420e650e1272byz buffer_length || data_length == 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Since we know the string will fit in the buffer, snprintf will
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * always return less than buffer_length, so we can just return
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * whatever snprintf returns.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (GENERATE_PROPERTY_STRING(buffer, buffer_length, "%s",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz name, DLADM_TYPE_STR, ptr));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic size_t
d62bc4badc1c1f1549c961cfb8b420e650e1272byzwrite_boolean(char *buffer, size_t buffer_length, char *name, void *value)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t *ptr = value;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Booleans are either zero or one, so we only need room for two
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * characters in the buffer.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (buffer_length <= 1 + BASE_PROPERTY_LENGTH(DLADM_TYPE_BOOLEAN, name))
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (GENERATE_PROPERTY_STRING(buffer, buffer_length, "%d",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz name, DLADM_TYPE_BOOLEAN, *ptr));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic size_t
d62bc4badc1c1f1549c961cfb8b420e650e1272byzwrite_uint64(char *buffer, size_t buffer_length, char *name, void *value)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint64_t *ptr = value;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Limit checking for uint64_t is a little trickier.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (snprintf(NULL, 0, "%lld", *ptr) +
d62bc4badc1c1f1549c961cfb8b420e650e1272byz BASE_PROPERTY_LENGTH(DLADM_TYPE_UINT64, name) >= buffer_length)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (GENERATE_PROPERTY_STRING(buffer, buffer_length, "%lld",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz name, DLADM_TYPE_UINT64, *ptr));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic size_t
d62bc4badc1c1f1549c961cfb8b420e650e1272byzread_str(char *buffer, void **value)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
024b0a258461f282a92b1b1283c3b8b083f9f33fseb char *ptr = calloc(MAXLINKATTRVALLEN, sizeof (char));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ssize_t len;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
024b0a258461f282a92b1b1283c3b8b083f9f33fseb if (ptr == NULL || (len = strlcpy(ptr, buffer, MAXLINKATTRVALLEN))
024b0a258461f282a92b1b1283c3b8b083f9f33fseb >= MAXLINKATTRVALLEN) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(ptr);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *(char **)value = ptr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Account for NULL terminator */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (len + 1);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic size_t
d62bc4badc1c1f1549c961cfb8b420e650e1272byzread_boolean(char *buffer, void **value)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t *ptr = calloc(1, sizeof (boolean_t));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (ptr == NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *ptr = atoi(buffer);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *(boolean_t **)value = ptr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (sizeof (boolean_t));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic size_t
d62bc4badc1c1f1549c961cfb8b420e650e1272byzread_int64(char *buffer, void **value)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int64_t *ptr = calloc(1, sizeof (int64_t));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (ptr == NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *ptr = (int64_t)atoll(buffer);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *(int64_t **)value = ptr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (sizeof (int64_t));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic dlmgmt_db_req_t *
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_db_req_alloc(dlmgmt_db_op_t op, const char *linkname,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy datalink_id_t linkid, zoneid_t zoneid, uint32_t flags, int *err)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_db_req_t *req;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((req = calloc(1, sizeof (dlmgmt_db_req_t))) == NULL) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy *err = errno;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy } else {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy req->ls_op = op;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (linkname != NULL)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) strlcpy(req->ls_link, linkname, MAXLINKNAMELEN);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy req->ls_linkid = linkid;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy req->ls_zoneid = zoneid;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy req->ls_flags = flags;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (req);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Update the db entry with name "entryname" using information from "linkp".
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_db_update(dlmgmt_db_op_t op, const char *entryname, dlmgmt_link_t *linkp,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy uint32_t flags)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_db_req_t *req;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int err;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* It is either a persistent request or an active request, not both. */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert((flags == DLMGMT_PERSIST) || (flags == DLMGMT_ACTIVE));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((req = dlmgmt_db_req_alloc(op, entryname, linkp->ll_linkid,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp->ll_zoneid, flags, &err)) == NULL)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If the return error is EINPROGRESS, this request is handled
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * asynchronously; return success.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz err = dlmgmt_process_db_req(req);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (err != EINPROGRESS)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(req);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz else
d62bc4badc1c1f1549c961cfb8b420e650e1272byz err = 0;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define DLMGMT_DB_OP_STR(op) \
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (((op) == DLMGMT_DB_OP_READ) ? "read" : \
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (((op) == DLMGMT_DB_OP_WRITE) ? "write" : "delete"))
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define DLMGMT_DB_CONF_STR(flag) \
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (((flag) == DLMGMT_ACTIVE) ? "active" : \
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (((flag) == DLMGMT_PERSIST) ? "persistent" : ""))
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdlmgmt_process_db_req(dlmgmt_db_req_t *req)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz pthread_t tid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t writeop;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int err;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If there are already pending "write" requests, queue this request in
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * the pending list. Note that this function is called while the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * dlmgmt_rw_lock is held, so it is safe to access the global variables.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz writeop = (req->ls_op != DLMGMT_DB_OP_READ);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (writeop && (req->ls_flags == DLMGMT_PERSIST) &&
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (dlmgmt_db_req_head != NULL)) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_db_req_tail->ls_next = req;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_db_req_tail = req;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (EINPROGRESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz err = dlmgmt_process_db_onereq(req, writeop);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (err != EINPROGRESS && err != 0 && err != ENOENT) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Log the error unless the request processing is still in
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * progress or if the configuration file hasn't been created
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * yet (ENOENT).
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_log(LOG_WARNING, "dlmgmt_process_db_onereq() %s "
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "operation on %s configuration failed: %s",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz DLMGMT_DB_OP_STR(req->ls_op),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz DLMGMT_DB_CONF_STR(req->ls_flags), strerror(err));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (err == EINPROGRESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(req->ls_flags == DLMGMT_PERSIST);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(writeop && dlmgmt_db_req_head == NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_db_req_tail = dlmgmt_db_req_head = req;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz err = pthread_create(&tid, NULL, dlmgmt_db_update_thread, NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (err == 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (EINPROGRESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdlmgmt_process_db_onereq(dlmgmt_db_req_t *req, boolean_t writeop)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int err = 0;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz FILE *fp, *nfp = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char file[MAXPATHLEN];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char newfile[MAXPATHLEN];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz DLMGMT_MAKE_FILE_DB_PATH(file, (req->ls_flags == DLMGMT_PERSIST));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy fp = dlmgmt_zfopen(file, "r", req->ls_zoneid, &err);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Note that it is not an error if the file doesn't exist. If we're
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * reading, we treat this case the same way as an empty file. If
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * we're writing, the file will be created when we open the file for
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * writing below.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (fp == NULL && !writeop)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (writeop) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(newfile, MAXPATHLEN, "%s.new", file);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy nfp = dlmgmt_zfopen(newfile, "w", req->ls_zoneid, &err);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (nfp == NULL) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * EROFS can happen at boot when the file system is
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * read-only. Return EINPROGRESS so that the caller
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * can add this request to the pending request list
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * and start a retry thread.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = (errno == EROFS ? EINPROGRESS : errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy goto done;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (writeop) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((err = process_db_write(req, fp, nfp)) == 0)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = dlmgmt_zrename(newfile, file, req->ls_zoneid);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy } else {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = process_db_read(req, fp);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdone:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (nfp != NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) fclose(nfp);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (err != 0)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) dlmgmt_zunlink(newfile, req->ls_zoneid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) fclose(fp);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void *
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdlmgmt_db_update_thread(void *arg)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_db_req_t *req;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_table_lock(B_TRUE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(dlmgmt_db_req_head != NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz while ((req = dlmgmt_db_req_head) != NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(req->ls_flags == DLMGMT_PERSIST);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (dlmgmt_process_db_onereq(req, B_TRUE) == EINPROGRESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * The filesystem is still read only. Go to sleep and
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * try again.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_table_unlock();
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) sleep(5);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_table_lock(B_TRUE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz continue;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * The filesystem is no longer read only. Continue processing
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * and remove the request from the pending list.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_db_req_head = req->ls_next;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (dlmgmt_db_req_tail == req) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz assert(dlmgmt_db_req_head == NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_db_req_tail = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(req);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_table_unlock();
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzparse_linkprops(char *buf, dlmgmt_link_t *linkp)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t found_type = B_FALSE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dladm_datatype_t type = DLADM_TYPE_STR;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int i, len;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int err = 0;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char *curr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char attr_name[MAXLINKATTRLEN];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz size_t attr_buf_len = 0;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz void *attr_buf = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz curr = buf;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz len = strlen(buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz attr_name[0] = '\0';
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (i = 0; i < len && err == 0; i++) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char c = buf[i];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t match = (c == '=' ||
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (c == ',' && !found_type) || c == ';');
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Move to the next character if there is no match and
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * if we have not reached the last character.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!match && i != len - 1)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz continue;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (match) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * NUL-terminate the string pointed to by 'curr'.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz buf[i] = '\0';
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (*curr == '\0')
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto parse_fail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (attr_name[0] != '\0' && found_type) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * We get here after we have processed the "<prop>="
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * pattern. The pattern we are now interested in is
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * "<val>;".
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (c == '=')
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto parse_fail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (strcmp(attr_name, "linkid") == 0) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) read_int64(curr, &attr_buf);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp->ll_linkid =
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (datalink_class_t)*(int64_t *)attr_buf;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy } else if (strcmp(attr_name, "name") == 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) read_str(curr, &attr_buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(linkp->ll_link,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz MAXLINKNAMELEN, "%s", attr_buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else if (strcmp(attr_name, "class") == 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) read_int64(curr, &attr_buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz linkp->ll_class =
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (datalink_class_t)*(int64_t *)attr_buf;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else if (strcmp(attr_name, "media") == 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) read_int64(curr, &attr_buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz linkp->ll_media =
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (uint32_t)*(int64_t *)attr_buf;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz attr_buf_len = translators[type].read_func(curr,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &attr_buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz err = linkattr_set(&(linkp->ll_head), attr_name,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz attr_buf, attr_buf_len, type);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz free(attr_buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz attr_name[0] = '\0';
d62bc4badc1c1f1549c961cfb8b420e650e1272byz found_type = B_FALSE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else if (attr_name[0] != '\0') {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Non-zero length attr_name and found_type of false
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * indicates that we have not found the type for this
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * attribute. The pattern now is "<type>,<val>;", we
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * want the <type> part of the pattern.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (type = 0; type < ntranslators; type++) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (strcmp(curr,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz translators[type].type_name) == 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz found_type = B_TRUE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!found_type)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto parse_fail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * A zero length attr_name indicates we are looking
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * at the beginning of a link attribute.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (c != '=')
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto parse_fail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(attr_name, MAXLINKATTRLEN, "%s", curr);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz curr = buf + i + 1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzparse_fail:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (-1);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic boolean_t
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Royprocess_link_line(char *buf, dlmgmt_link_t *linkp)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int i, len, llen;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy char *str, *lasts;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy char tmpbuf[MAXLINELEN];
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy bzero(linkp, sizeof (*linkp));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp->ll_linkid = DATALINK_INVALID_LINKID;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Use a copy of buf for parsing so that we can do whatever we want.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) strlcpy(tmpbuf, buf, MAXLINELEN);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Skip leading spaces, blank lines, and comments.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz len = strlen(tmpbuf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (i = 0; i < len; i++) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!isspace(tmpbuf[i]))
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (i == len || tmpbuf[i] == '#')
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (B_TRUE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz str = tmpbuf + i;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Find the link name and assign it to the link structure.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (strtok_r(str, " \n\t", &lasts) == NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto fail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz llen = strlen(str);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Note that a previous version of the persistent datalink.conf file
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * stored the linkid as the first field. In that case, the name will
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * be obtained through parse_linkprops from a property with the format
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * "name=<linkname>". If we encounter such a format, we set
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * rewrite_needed so that dlmgmt_db_init() can rewrite the file with
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * the new format after it's done reading in the data.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (isdigit(str[0])) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp->ll_linkid = atoi(str);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy rewrite_needed = B_TRUE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy } else {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (strlcpy(linkp->ll_link, str, sizeof (linkp->ll_link)) >=
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy sizeof (linkp->ll_link))
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy goto fail;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz str += llen + 1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (str >= tmpbuf + len)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto fail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Now find the list of link properties.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((str = strtok_r(str, " \n\t", &lasts)) == NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto fail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (parse_linkprops(str, linkp) < 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto fail;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (B_TRUE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzfail:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Delete corrupted line.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz buf[0] = '\0';
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (B_FALSE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Find any properties in linkp that refer to "old", and rename to "new".
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Return B_TRUE if any renaming occurred.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_attr_rename(dlmgmt_link_t *linkp, const char *old, const char *new,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy boolean_t *renamed)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_linkattr_t *attrp;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy char *newval = NULL, *pname;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy char valcp[MAXLINKATTRVALLEN];
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy size_t newsize;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy *renamed = B_FALSE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((attrp = linkattr_find(linkp->ll_head, "linkover")) != NULL ||
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (attrp = linkattr_find(linkp->ll_head, "simnetpeer")) != NULL) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (strcmp(old, (char *)attrp->lp_val) == 0) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy newsize = strlen(new) + 1;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((newval = malloc(newsize)) == NULL)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) strcpy(newval, new);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy free(attrp->lp_val);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy attrp->lp_val = newval;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy attrp->lp_sz = newsize;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy *renamed = B_TRUE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (0);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((attrp = linkattr_find(linkp->ll_head, "portnames")) == NULL)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (0);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* <linkname>:[<linkname>:]... */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((newval = calloc(MAXLINKATTRVALLEN, sizeof (char))) == NULL)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (errno);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy bcopy(attrp->lp_val, valcp, sizeof (valcp));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy pname = strtok(valcp, ":");
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy while (pname != NULL) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (strcmp(pname, old) == 0) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) strcat(newval, new);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy *renamed = B_TRUE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy } else {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) strcat(newval, pname);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) strcat(newval, ":");
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy pname = strtok(NULL, ":");
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (*renamed) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy free(attrp->lp_val);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy attrp->lp_val = newval;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy attrp->lp_sz = strlen(newval) + 1;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy } else {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy free(newval);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (0);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzprocess_db_write(dlmgmt_db_req_t *req, FILE *fp, FILE *nfp)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz boolean_t done = B_FALSE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int err = 0;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_link_t link_in_file, *linkp = NULL, *dblinkp;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy boolean_t persist = (req->ls_flags == DLMGMT_PERSIST);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy boolean_t writeall, rename, attr_renamed;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char buf[MAXLINELEN];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy writeall = (req->ls_linkid == DATALINK_ALL_LINKID);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (req->ls_op == DLMGMT_DB_OP_WRITE && !writeall) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * find the link in the avl tree with the given linkid.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp = link_by_id(req->ls_linkid, req->ls_zoneid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (linkp == NULL || (linkp->ll_flags & req->ls_flags) == 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This link has already been changed. This could
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * happen if the request is pending because of
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * read-only file-system. If so, we are done.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * In the case of a rename, linkp's name has been updated to
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * the new name, and req->ls_link is the old link name.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy rename = (strcmp(req->ls_link, linkp->ll_link) != 0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * fp can be NULL if the file didn't initially exist and we're
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * creating it as part of this write operation.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (fp == NULL)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy goto write;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
d62bc4badc1c1f1549c961cfb8b420e650e1272byz while (err == 0 && fgets(buf, sizeof (buf), fp) != NULL &&
d62bc4badc1c1f1549c961cfb8b420e650e1272byz process_link_line(buf, &link_in_file)) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (link_in_file.ll_link[0] == '\0' || done) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * this is a comment line or we are done updating the
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * line for the specified link, write the rest of
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * lines out.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (fputs(buf, nfp) == EOF)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz err = errno;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz continue;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz switch (req->ls_op) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz case DLMGMT_DB_OP_WRITE:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * For write operations, we generate a new output line
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * if we're either writing all links (writeall) or if
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * the name of the link in the file matches the one
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * we're looking for. Otherwise, we write out the
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * buffer as-is.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy *
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * If we're doing a rename operation, ensure that any
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * references to the link being renamed in link
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * properties are also updated before we write
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * anything.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (writeall) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp = link_by_name(link_in_file.ll_link,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy req->ls_zoneid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (writeall || strcmp(req->ls_link,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_in_file.ll_link) == 0) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy generate_link_line(linkp, persist, buf);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (!writeall && !rename)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy done = B_TRUE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy } else if (rename && persist) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dblinkp = link_by_name(link_in_file.ll_link,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy req->ls_zoneid);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = dlmgmt_attr_rename(dblinkp, req->ls_link,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp->ll_link, &attr_renamed);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (err != 0)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy break;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (attr_renamed) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy generate_link_line(dblinkp, persist,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy buf);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (fputs(buf, nfp) == EOF)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = errno;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz case DLMGMT_DB_OP_DELETE:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Delete is simple. If buf does not represent the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * link we're deleting, write it out.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (strcmp(req->ls_link, link_in_file.ll_link) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (fputs(buf, nfp) == EOF)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz err = errno;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz done = B_TRUE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz case DLMGMT_DB_OP_READ:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz default:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz err = EINVAL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roywrite:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * If we get to the end of the file and have not seen what linkid
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * points to, write it out then.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (req->ls_op == DLMGMT_DB_OP_WRITE && !writeall && !rename && !done) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy generate_link_line(linkp, persist, buf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz done = B_TRUE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (fputs(buf, nfp) == EOF)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz err = errno;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Royprocess_db_read(dlmgmt_db_req_t *req, FILE *fp)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz avl_index_t name_where, id_where;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_link_t link_in_file, *newlink, *link_in_db;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char buf[MAXLINELEN];
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int err = 0;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This loop processes each line of the configuration file.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz while (fgets(buf, MAXLINELEN, fp) != NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (!process_link_line(buf, &link_in_file)) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz err = EINVAL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Skip the comment line.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (link_in_file.ll_link[0] == '\0')
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy continue;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((req->ls_flags & DLMGMT_ACTIVE) &&
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_in_file.ll_linkid == DATALINK_INVALID_LINKID)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz continue;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_in_file.ll_zoneid = req->ls_zoneid;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_in_db = avl_find(&dlmgmt_name_avl, &link_in_file,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy &name_where);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (link_in_db != NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * If the link in the database already has the flag
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * for this request set, then the entry is a
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * duplicate. If it's not a duplicate, then simply
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * turn on the appropriate flag on the existing link.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (link_in_db->ll_flags & req->ls_flags) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_log(LOG_WARNING, "Duplicate links "
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy "in the repository: %s",
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_in_file.ll_link);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (req->ls_flags & DLMGMT_PERSIST) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Save the newly read properties into
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * the existing link.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy assert(link_in_db->ll_head == NULL);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_in_db->ll_head =
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_in_file.ll_head;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_in_db->ll_flags |= req->ls_flags;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * This is a new link. Allocate a new dlmgmt_link_t
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * and add it to the trees.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy newlink = calloc(1, sizeof (*newlink));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (newlink == NULL) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_log(LOG_WARNING, "Unable to allocate "
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy "memory to create new link %s",
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_in_file.ll_link);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy continue;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy bcopy(&link_in_file, newlink, sizeof (*newlink));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (newlink->ll_linkid == DATALINK_INVALID_LINKID)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy newlink->ll_linkid = dlmgmt_nextlinkid;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (avl_find(&dlmgmt_id_avl, newlink, &id_where) !=
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy NULL) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_destroy(newlink);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy continue;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((req->ls_flags & DLMGMT_ACTIVE) &&
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_activate(newlink) != 0) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_log(LOG_WARNING, "Unable to activate %s",
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy newlink->ll_link);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy link_destroy(newlink);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy continue;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy avl_insert(&dlmgmt_name_avl, newlink, name_where);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy avl_insert(&dlmgmt_id_avl, newlink, id_where);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_advance(newlink);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy newlink->ll_flags |= req->ls_flags;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Generate an entry in the link database.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Each entry has this format:
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * <link name> <prop0>=<type>,<val>;...;<propn>=<type>,<val>;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzgenerate_link_line(dlmgmt_link_t *linkp, boolean_t persist, char *buf)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char tmpbuf[MAXLINELEN];
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy char *ptr = tmpbuf;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char *lim = tmpbuf + MAXLINELEN;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlmgmt_linkattr_t *cur_p = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz uint64_t u64;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s\t", linkp->ll_link);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (!persist) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * We store the linkid in the active database so that dlmgmtd
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * can recover in the event that it is restarted.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy u64 = linkp->ll_linkid;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ptr += write_uint64(ptr, BUFLEN(lim, ptr), "linkid", &u64);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz u64 = linkp->ll_class;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ptr += write_uint64(ptr, BUFLEN(lim, ptr), "class", &u64);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz u64 = linkp->ll_media;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ptr += write_uint64(ptr, BUFLEN(lim, ptr), "media", &u64);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * The daemon does not keep any active link attribute. Only store the
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * attributes if this request is for persistent configuration,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (persist) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy for (cur_p = linkp->ll_head; cur_p != NULL;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy cur_p = cur_p->lp_next) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ptr += translators[cur_p->lp_type].write_func(ptr,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy BUFLEN(lim, ptr), cur_p->lp_name, cur_p->lp_val);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (ptr <= lim)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) snprintf(buf, MAXLINELEN, "%s\n", tmpbuf);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzint
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_delete_db_entry(dlmgmt_link_t *linkp, uint32_t flags)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (dlmgmt_db_update(DLMGMT_DB_OP_DELETE, linkp->ll_link, linkp,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy flags));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzint
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_write_db_entry(const char *entryname, dlmgmt_link_t *linkp,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy uint32_t flags)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy int err;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (flags & DLMGMT_PERSIST) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((err = dlmgmt_db_update(DLMGMT_DB_OP_WRITE, entryname,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp, DLMGMT_PERSIST)) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (flags & DLMGMT_ACTIVE) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (((err = dlmgmt_db_update(DLMGMT_DB_OP_WRITE, entryname,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp, DLMGMT_ACTIVE)) != 0) && (flags & DLMGMT_PERSIST)) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) dlmgmt_db_update(DLMGMT_DB_OP_DELETE, entryname,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp, DLMGMT_PERSIST);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Upgrade properties that have link IDs as values to link names. Because '.'
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * is a valid linkname character, the port separater for link aggregations
d501bbfebe95a313ee5e78368177b1667a71c628Sebastien Roy * must be changed to ':'.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic void
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roylinkattr_upgrade(dlmgmt_linkattr_t *attrp)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy datalink_id_t linkid;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy char *portidstr;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy char portname[MAXLINKNAMELEN + 1];
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_link_t *linkp;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy char *new_attr_val;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy size_t new_attr_sz;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy boolean_t upgraded = B_FALSE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (strcmp(attrp->lp_name, "linkover") == 0 ||
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy strcmp(attrp->lp_name, "simnetpeer") == 0) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (attrp->lp_type == DLADM_TYPE_UINT64) {
d501bbfebe95a313ee5e78368177b1667a71c628Sebastien Roy linkid = (datalink_id_t)*(uint64_t *)attrp->lp_val;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((linkp = link_by_id(linkid, GLOBAL_ZONEID)) == NULL)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy new_attr_sz = strlen(linkp->ll_link) + 1;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((new_attr_val = malloc(new_attr_sz)) == NULL)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) strcpy(new_attr_val, linkp->ll_link);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy upgraded = B_TRUE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy } else if (strcmp(attrp->lp_name, "portnames") == 0) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * The old format for "portnames" was
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * "<linkid>.[<linkid>.]...". The new format is
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * "<linkname>:[<linkname>:]...".
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (!isdigit(((char *)attrp->lp_val)[0]))
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy new_attr_val = calloc(MAXLINKATTRVALLEN, sizeof (char));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (new_attr_val == NULL)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy portidstr = (char *)attrp->lp_val;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy while (*portidstr != '\0') {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy errno = 0;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkid = strtol(portidstr, &portidstr, 10);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (linkid == 0 || *portidstr != '.' ||
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (linkp = link_by_id(linkid, GLOBAL_ZONEID)) ==
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy NULL) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy free(new_attr_val);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) snprintf(portname, sizeof (portname), "%s:",
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp->ll_link);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (strlcat(new_attr_val, portname,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy MAXLINKATTRVALLEN) >= MAXLINKATTRVALLEN) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy free(new_attr_val);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* skip the '.' delimiter */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy portidstr++;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy new_attr_sz = strlen(new_attr_val) + 1;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy upgraded = B_TRUE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (upgraded) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy attrp->lp_type = DLADM_TYPE_STR;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy attrp->lp_sz = new_attr_sz;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy free(attrp->lp_val);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy attrp->lp_val = new_attr_val;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic void
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_db_upgrade(dlmgmt_link_t *linkp)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_linkattr_t *attrp;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy for (attrp = linkp->ll_head; attrp != NULL; attrp = attrp->lp_next)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkattr_upgrade(attrp);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic void
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_db_phys_activate(dlmgmt_link_t *linkp)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp->ll_flags |= DLMGMT_ACTIVE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) dlmgmt_write_db_entry(linkp->ll_link, linkp, DLMGMT_ACTIVE);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic void
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_db_walk(zoneid_t zoneid, datalink_class_t class, db_walk_func_t *func)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_link_t *linkp;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy for (linkp = avl_first(&dlmgmt_id_avl); linkp != NULL;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp = AVL_NEXT(&dlmgmt_id_avl, linkp)) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (linkp->ll_zoneid == zoneid && (linkp->ll_class & class))
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy func(linkp);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Initialize the datalink <link name, linkid> mapping and the link's
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * attributes list based on the configuration file /etc/dladm/datalink.conf
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * and the active configuration cache file
b9e076dcc05b713d74073c0d692dfbb0f6f2c594yz * /etc/svc/volatile/dladm/datalink-management:default.cache.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzint
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_db_init(zoneid_t zoneid)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_db_req_t *req;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int err;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy boolean_t boot = B_FALSE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((req = dlmgmt_db_req_alloc(DLMGMT_DB_OP_READ, NULL,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy DATALINK_INVALID_LINKID, zoneid, DLMGMT_ACTIVE, &err)) == NULL)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((err = dlmgmt_process_db_req(req)) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * If we get back ENOENT, that means that the active
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * configuration file doesn't exist yet, and is not an error.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * We'll create it down below after we've loaded the
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * persistent configuration.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (err != ENOENT)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy goto done;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy boot = B_TRUE;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy req->ls_flags = DLMGMT_PERSIST;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = dlmgmt_process_db_req(req);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (err != 0 && err != ENOENT)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz goto done;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = 0;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (rewrite_needed) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * First update links in memory, then dump the entire db to
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * disk.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_db_walk(zoneid, DATALINK_CLASS_ALL, dlmgmt_db_upgrade);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy req->ls_op = DLMGMT_DB_OP_WRITE;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy req->ls_linkid = DATALINK_ALL_LINKID;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if ((err = dlmgmt_process_db_req(req)) != 0 &&
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err != EINPROGRESS)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy goto done;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (boot) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_db_walk(zoneid, DATALINK_CLASS_PHYS,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_db_phys_activate);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdone:
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (err == EINPROGRESS)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy err = 0;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy else
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy free(req);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/*
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Remove all links in the given zoneid.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Royvoid
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roydlmgmt_db_fini(zoneid_t zoneid)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy{
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy dlmgmt_link_t *linkp = avl_first(&dlmgmt_name_avl), *next_linkp;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy while (linkp != NULL) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy next_linkp = AVL_NEXT(&dlmgmt_name_avl, linkp);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (linkp->ll_zoneid == zoneid) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (void) dlmgmt_destroy_common(linkp,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy DLMGMT_ACTIVE | DLMGMT_PERSIST);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy linkp = next_linkp;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy }
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy}