diff options
Diffstat (limited to 'usr/src/lib/libpool')
| -rw-r--r-- | usr/src/lib/libpool/common/pool.c | 126 | ||||
| -rw-r--r-- | usr/src/lib/libpool/common/pool.h | 9 | ||||
| -rw-r--r-- | usr/src/lib/libpool/common/pool_commit.c | 17 | ||||
| -rw-r--r-- | usr/src/lib/libpool/common/pool_internal.c | 24 | ||||
| -rw-r--r-- | usr/src/lib/libpool/common/pool_internal.h | 9 | ||||
| -rw-r--r-- | usr/src/lib/libpool/common/pool_kernel.c | 23 |
6 files changed, 177 insertions, 31 deletions
diff --git a/usr/src/lib/libpool/common/pool.c b/usr/src/lib/libpool/common/pool.c index 167cd8be5b..6fbd7b34d3 100644 --- a/usr/src/lib/libpool/common/pool.c +++ b/usr/src/lib/libpool/common/pool.c @@ -914,10 +914,34 @@ pool_put_property(pool_conf_t *conf, pool_elem_t *pe, const char *name, return (NULL); } - if (!is_valid_prop_name(name)) { + /* Don't allow (re)setting of the "temporary" property */ + if (!is_valid_prop_name(name) || strstr(name, ".temporary") != NULL) { pool_seterror(POE_BADPARAM); return (PO_FAIL); } + + /* Don't allow rename of temporary pools/resources */ + if (strstr(name, ".name") != NULL && elem_is_tmp(pe)) { + boolean_t rename = B_TRUE; + pool_value_t *pv = pool_value_alloc(); + + if (pe->pe_get_prop(pe, name, pv) != POC_INVAL) { + const char *s1 = NULL; + const char *s2 = NULL; + + (void) pool_value_get_string(pv, &s1); + (void) pool_value_get_string(val, &s2); + if (s1 != NULL && s2 != NULL && strcmp(s1, s2) == 0) + rename = B_FALSE; + } + pool_value_free(pv); + + if (rename) { + pool_seterror(POE_BADPARAM); + return (PO_FAIL); + } + } + /* * Check to see if this is a property we are managing. If it is, * ensure that we are happy with what the user is doing. @@ -936,6 +960,46 @@ pool_put_property(pool_conf_t *conf, pool_elem_t *pe, const char *name, } /* + * Set temporary property to flag as a temporary element. + * + * PO_FAIL is returned if an error is detected and the error code is updated + * to indicate the cause of the error. + */ +int +pool_set_temporary(pool_conf_t *conf, pool_elem_t *pe) +{ + int res; + char name[128]; + pool_value_t *val; + + if (pool_conf_check(conf) != PO_SUCCESS) + return (PO_FAIL); + + if (TO_CONF(pe) != conf) { + pool_seterror(POE_BADPARAM); + return (PO_FAIL); + } + + /* create property name based on element type */ + if (snprintf(name, sizeof (name), "%s.temporary", + pool_elem_class_string(pe)) > sizeof (name)) { + pool_seterror(POE_SYSTEM); + return (PO_FAIL); + } + + if ((val = pool_value_alloc()) == NULL) + return (PO_FAIL); + + pool_value_set_bool(val, (uchar_t)1); + + res = pe->pe_put_prop(pe, name, val); + + pool_value_free(val); + + return (res); +} + +/* * Update the specified property value with the namespace prepended. * e.g. If this function is used to update the property "name" on a pool, it * will attempt to update "pool.name". @@ -1030,6 +1094,12 @@ pool_rm_property(pool_conf_t *conf, pool_elem_t *pe, const char *name) return (NULL); } + /* Don't allow removal of the "temporary" property */ + if (strstr(name, ".temporary") != NULL) { + pool_seterror(POE_BADPARAM); + return (PO_FAIL); + } + /* * Check to see if this is a property we are managing. If it is, * ensure that we are happy with what the user is doing. @@ -1122,6 +1192,17 @@ pool_create(pool_conf_t *conf, const char *name) pool_seterror(POE_PUTPROP); return (NULL); } + + /* + * If we are creating a temporary pool configuration, flag the pool. + */ + if (conf->pc_prov->pc_oflags & PO_TEMP) { + if (pool_set_temporary(conf, pe) == PO_FAIL) { + (void) pool_destroy(conf, pool_elem_pool(pe)); + return (NULL); + } + } + return (pool_elem_pool(pe)); } @@ -1227,6 +1308,17 @@ pool_resource_create(pool_conf_t *conf, const char *sz_type, const char *name) return (NULL); } } + + /* + * If we are creating a temporary pool configuration, flag the resource. + */ + if (conf->pc_prov->pc_oflags & PO_TEMP) { + if (pool_set_temporary(conf, pe) != PO_SUCCESS) { + (void) pool_resource_destroy(conf, pool_elem_res(pe)); + return (NULL); + } + } + return (pool_elem_res(pe)); } @@ -1396,7 +1488,8 @@ pool_conf_open(pool_conf_t *conf, const char *location, int oflags) pool_seterror(POE_BADPARAM); return (PO_FAIL); } - if (oflags & ~(PO_RDONLY | PO_RDWR | PO_CREAT | PO_DISCO | PO_UPDATE)) { + if (oflags & ~(PO_RDONLY | PO_RDWR | PO_CREAT | PO_DISCO | PO_UPDATE | + PO_TEMP)) { pool_seterror(POE_BADPARAM); return (PO_FAIL); } @@ -1408,6 +1501,10 @@ pool_conf_open(pool_conf_t *conf, const char *location, int oflags) if (oflags & PO_CREAT) oflags |= PO_RDWR; + /* location is ignored when creating a temporary configuration */ + if (oflags & PO_TEMP) + location = ""; + if ((conf->pc_location = strdup(location)) == NULL) { pool_seterror(POE_SYSTEM); return (PO_FAIL); @@ -1415,14 +1512,25 @@ pool_conf_open(pool_conf_t *conf, const char *location, int oflags) /* * This is the crossover point into the actual data provider * implementation, allocate a data provider of the appropriate - * type for your data storage medium. In this case it's a kernel - * data provider. To use a different data provider, write some - * code to implement all the required interfaces and then - * change the next line to allocate a data provider which uses your - * new code. All data provider routines can be static, apart from - * the allocation routine. + * type for your data storage medium. In this case it's either a kernel + * or xml data provider. To use a different data provider, write some + * code to implement all the required interfaces and then change the + * following code to allocate a data provider which uses your new code. + * All data provider routines can be static, apart from the allocation + * routine. + * + * For temporary pools (PO_TEMP) we start with a copy of the current + * dynamic configuration and do all of the updates in-memory. */ - if (strcmp(location, pool_dynamic_location()) == 0) { + if (oflags & PO_TEMP) { + if (pool_knl_connection_alloc(conf, PO_TEMP) != PO_SUCCESS) { + conf->pc_state = POF_INVALID; + return (PO_FAIL); + } + /* set rdwr flag so we can updated the in-memory config. */ + conf->pc_prov->pc_oflags |= PO_RDWR; + + } else if (strcmp(location, pool_dynamic_location()) == 0) { if (pool_knl_connection_alloc(conf, oflags) != PO_SUCCESS) { conf->pc_state = POF_INVALID; return (PO_FAIL); diff --git a/usr/src/lib/libpool/common/pool.h b/usr/src/lib/libpool/common/pool.h index d38e9902e6..ee11aadb7b 100644 --- a/usr/src/lib/libpool/common/pool.h +++ b/usr/src/lib/libpool/common/pool.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -96,6 +95,7 @@ extern uint_t pool_version(uint_t ver); #define PO_CREAT 0x2 #define PO_DISCO 0x4 #define PO_UPDATE 0x8 +#define PO_TEMP 0x10 /* Allocation policy */ #define POA_IMPORTANCE "importance based" @@ -218,6 +218,7 @@ extern pool_value_class_t pool_get_property(const pool_conf_t *, extern int pool_put_property(pool_conf_t *, pool_elem_t *, const char *, const pool_value_t *); extern int pool_rm_property(pool_conf_t *, pool_elem_t *, const char *); + /* * Walk the associated properties of the supplied element calling the supplied * function for each property in turn. There is no implied order in the walk. diff --git a/usr/src/lib/libpool/common/pool_commit.c b/usr/src/lib/libpool/common/pool_commit.c index 1ea4808377..b996524b98 100644 --- a/usr/src/lib/libpool/common/pool_commit.c +++ b/usr/src/lib/libpool/common/pool_commit.c @@ -245,6 +245,9 @@ commit_delete(pool_elem_t *pe) pool_t *pool; int ret = 0; + if (elem_is_tmp(pe)) + return (PO_SUCCESS); + switch (pool_elem_class(pe)) { case PEC_SYSTEM: /* NO-OP */ break; @@ -1306,7 +1309,14 @@ clone_element(pool_conf_t *conf, pool_elem_t *pe, const char *name, if ((prop = provider_get_prop(pe, name)) != NULL && prop_is_readonly(prop) == PO_TRUE) return (PO_SUCCESS); - return (pool_put_property(TO_CONF(tgt), tgt, name, pv) == PO_FAIL); + + /* The temporary property needs special handling */ + if (strstr(name, ".temporary") != NULL) + return (pool_set_temporary(TO_CONF(tgt), tgt) == + PO_FAIL ? PO_FAIL : PO_SUCCESS); + else + return (pool_put_property(TO_CONF(tgt), tgt, name, pv) == + PO_FAIL ? PO_FAIL : PO_SUCCESS); } /* @@ -1322,8 +1332,9 @@ clean_element(pool_conf_t *conf, pool_elem_t *pe, const char *name, /* * Some properties should be ignored */ - if ((prop = provider_get_prop(pe, name)) != NULL && - prop_is_optional(prop) == PO_FALSE) + if (strstr(name, ".temporary") != NULL || + ((prop = provider_get_prop(pe, name)) != NULL && + prop_is_optional(prop) == PO_FALSE)) return (PO_SUCCESS); return (pool_rm_property(conf, (pool_elem_t *)pe, name) == PO_FAIL); } diff --git a/usr/src/lib/libpool/common/pool_internal.c b/usr/src/lib/libpool/common/pool_internal.c index 210e63d620..5e572f6eaf 100644 --- a/usr/src/lib/libpool/common/pool_internal.c +++ b/usr/src/lib/libpool/common/pool_internal.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1143,6 +1142,23 @@ elem_is_default(const pool_elem_t *res) } /* + * Return B_TRUE if the element has the 'temporary' property set. + */ +boolean_t +elem_is_tmp(const pool_elem_t *elem) +{ + pool_value_t val = POOL_VALUE_INITIALIZER; + uchar_t bval; + + if (pool_get_ns_property(elem, "temporary", &val) != POC_BOOL) + return (B_FALSE); + + (void) pool_value_get_bool(&val, &bval); + + return (bval != 0); +} + +/* * get_default_elem() returns the default elem for type of the supplied * elem. * diff --git a/usr/src/lib/libpool/common/pool_internal.h b/usr/src/lib/libpool/common/pool_internal.h index 592c98d11d..e172d23af4 100644 --- a/usr/src/lib/libpool/common/pool_internal.h +++ b/usr/src/lib/libpool/common/pool_internal.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -256,6 +255,7 @@ extern int resource_get_pinned(const pool_resource_t *, extern char *elem_get_name(const pool_elem_t *); extern id_t elem_get_sysid(const pool_elem_t *); extern int elem_is_default(const pool_elem_t *); +extern boolean_t elem_is_tmp(const pool_elem_t *); extern const pool_elem_t *get_default_elem(const pool_elem_t *); extern int qsort_elem_compare(const void *, const void *); @@ -371,6 +371,7 @@ extern pool_value_class_t pool_get_ns_property(const pool_elem_t *, extern int pool_walk_any_properties(pool_conf_t *, pool_elem_t *, void *, int (*)(pool_conf_t *, pool_elem_t *, const char *, pool_value_t *, void *), int); +extern int pool_set_temporary(pool_conf_t *, pool_elem_t *); /* * Namespace aware utility functions. diff --git a/usr/src/lib/libpool/common/pool_kernel.c b/usr/src/lib/libpool/common/pool_kernel.c index f84d6f2ba5..3da4f0263c 100644 --- a/usr/src/lib/libpool/common/pool_kernel.c +++ b/usr/src/lib/libpool/common/pool_kernel.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -646,10 +645,14 @@ pool_knl_close(pool_conf_t *conf) } /* * Rollback any pending changes before freeing the prov. This - * ensures there are no memory leaks from pending - * transactions. + * ensures there are no memory leaks from pending transactions. + * However, don't rollback when we've done a temporary pool since the + * pool/resources haven't really been committed in this case. + * They will all be freed in pool_knl_connection_free and we don't + * want to double free them. */ - (void) pool_knl_rollback(conf); + if (!(conf->pc_prov->pc_oflags & PO_TEMP)) + (void) pool_knl_rollback(conf); pool_knl_connection_free(prov); return (PO_SUCCESS); } @@ -997,6 +1000,9 @@ pool_knl_export(const pool_conf_t *conf, const char *location, const char *sep = ""; int j; + if (elem_is_tmp(elem)) + continue; + if ((info.ktx_node = node_create(system, BAD_CAST element_class_tags [pool_elem_class(elem)])) == NULL) { @@ -1072,6 +1078,9 @@ pool_knl_export(const pool_conf_t *conf, const char *location, uint_t ncompelem; int j; + if (elem_is_tmp(elem)) + continue; + if ((info.ktx_node = node_create(system, BAD_CAST element_class_tags [pool_elem_class(elem)])) == NULL) { |
