summaryrefslogtreecommitdiff
path: root/usr/src/lib/libpool
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libpool')
-rw-r--r--usr/src/lib/libpool/common/pool.c126
-rw-r--r--usr/src/lib/libpool/common/pool.h9
-rw-r--r--usr/src/lib/libpool/common/pool_commit.c17
-rw-r--r--usr/src/lib/libpool/common/pool_internal.c24
-rw-r--r--usr/src/lib/libpool/common/pool_internal.h9
-rw-r--r--usr/src/lib/libpool/common/pool_kernel.c23
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) {