[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] tools/xenstore: move xenstored sources into dedicated directory
commit 5c293058b130f50b881d4a9895a9a23f080b0ba8 Author: Juergen Gross <jgross@xxxxxxxx> AuthorDate: Tue Aug 22 09:45:02 2023 +0200 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Wed Aug 23 19:10:37 2023 +0100 tools/xenstore: move xenstored sources into dedicated directory In tools/xenstore there are living xenstored and xenstore clients. They are no longer sharing anything apart from the "xenstore" in their names. Move the xenstored sources into a new directory tools/xenstored while dropping the "xenstored_" prefix from their names. This will make it clearer that xenstore clients and xenstored are independent from each other. In order to avoid two very similar named directories below tools, rename tools/xenstore to tools/xs-clients. Drop the make targets [un]install-clients as those are not used in the Xen tree. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> Reviewed-by: Julien Grall <jgrall@xxxxxxxxxx> Acked-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- .gitignore | 11 - MAINTAINERS | 3 +- stubdom/Makefile | 4 +- tools/Makefile | 3 +- tools/xenstore/Makefile | 101 - tools/xenstore/Makefile.common | 30 - tools/xenstore/README | 5 - tools/xenstore/hashtable.c | 316 --- tools/xenstore/hashtable.h | 152 -- tools/xenstore/include/xenstore_state.h | 131 -- tools/xenstore/list.h | 283 --- tools/xenstore/talloc.c | 1323 ------------ tools/xenstore/talloc.h | 135 -- tools/xenstore/talloc_guide.txt | 569 ----- tools/xenstore/utils.c | 81 - tools/xenstore/utils.h | 74 - tools/xenstore/xenstore_client.c | 838 -------- tools/xenstore/xenstore_control.c | 375 ---- tools/xenstore/xenstored_control.c | 376 ---- tools/xenstore/xenstored_control.h | 20 - tools/xenstore/xenstored_core.c | 3541 ------------------------------- tools/xenstore/xenstored_core.h | 477 ----- tools/xenstore/xenstored_domain.c | 1874 ---------------- tools/xenstore/xenstored_domain.h | 170 -- tools/xenstore/xenstored_lu.c | 408 ---- tools/xenstore/xenstored_lu.h | 81 - tools/xenstore/xenstored_lu_daemon.c | 130 -- tools/xenstore/xenstored_lu_minios.c | 118 - tools/xenstore/xenstored_minios.c | 56 - tools/xenstore/xenstored_osdep.h | 20 - tools/xenstore/xenstored_posix.c | 159 -- tools/xenstore/xenstored_transaction.c | 625 ------ tools/xenstore/xenstored_transaction.h | 61 - tools/xenstore/xenstored_watch.c | 353 --- tools/xenstore/xenstored_watch.h | 41 - tools/xenstored/.gitignore | 1 + tools/xenstored/Makefile | 48 + tools/xenstored/Makefile.common | 29 + tools/xenstored/README | 5 + tools/xenstored/control.c | 376 ++++ tools/xenstored/control.h | 20 + tools/xenstored/core.c | 3541 +++++++++++++++++++++++++++++++ tools/xenstored/core.h | 477 +++++ tools/xenstored/domain.c | 1874 ++++++++++++++++ tools/xenstored/domain.h | 170 ++ tools/xenstored/hashtable.c | 316 +++ tools/xenstored/hashtable.h | 152 ++ tools/xenstored/list.h | 283 +++ tools/xenstored/lu.c | 408 ++++ tools/xenstored/lu.h | 81 + tools/xenstored/lu_daemon.c | 130 ++ tools/xenstored/lu_minios.c | 118 + tools/xenstored/minios.c | 56 + tools/xenstored/osdep.h | 20 + tools/xenstored/posix.c | 159 ++ tools/xenstored/talloc.c | 1323 ++++++++++++ tools/xenstored/talloc.h | 135 ++ tools/xenstored/talloc_guide.txt | 569 +++++ tools/xenstored/transaction.c | 625 ++++++ tools/xenstored/transaction.h | 61 + tools/xenstored/utils.c | 81 + tools/xenstored/utils.h | 74 + tools/xenstored/watch.c | 353 +++ tools/xenstored/watch.h | 41 + tools/xenstored/xenstore_state.h | 131 ++ tools/xs-clients/.gitignore | 10 + tools/xs-clients/Makefile | 69 + tools/xs-clients/xenstore_client.c | 838 ++++++++ tools/xs-clients/xenstore_control.c | 375 ++++ 69 files changed, 12955 insertions(+), 12938 deletions(-) diff --git a/.gitignore b/.gitignore index c1b73b0968..50273adb8d 100644 --- a/.gitignore +++ b/.gitignore @@ -237,17 +237,6 @@ tools/xenmon/xentrace_setmask tools/xenmon/xenbaked tools/xenpaging/xenpaging tools/xenpmd/xenpmd -tools/xenstore/xenstore -tools/xenstore/xenstore-chmod -tools/xenstore/xenstore-control -tools/xenstore/xenstore-exists -tools/xenstore/xenstore-list -tools/xenstore/xenstore-ls -tools/xenstore/xenstore-read -tools/xenstore/xenstore-rm -tools/xenstore/xenstore-watch -tools/xenstore/xenstore-write -tools/xenstore/xenstored tools/xentop/xentop tools/xentrace/xentrace_setsize tools/xentrace/tbctl diff --git a/MAINTAINERS b/MAINTAINERS index a0805d35cd..bf71ac144c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -669,7 +669,8 @@ F: tools/include/xenstore.h F: tools/include/xenstore_lib.h F: tools/include/xen-tools/xenstore-common.h F: tools/libs/store/ -F: tools/xenstore/ +F: tools/xenstored/ +F: tools/xs-clients/ XENTRACE M: George Dunlap <george.dunlap@xxxxxxxxxx> diff --git a/stubdom/Makefile b/stubdom/Makefile index 23ea8bb92e..0ddfce1ba2 100644 --- a/stubdom/Makefile +++ b/stubdom/Makefile @@ -371,10 +371,10 @@ endef $(foreach lib,$(STUB_LIBS),$(eval $(call BUILD_lib,$(lib)))) -xenstore/stamp: $(XEN_ROOT)/tools/xenstore/Makefile.common +xenstore/stamp: $(XEN_ROOT)/tools/xenstored/Makefile.common $(do_links) -xenstorepvh/stamp: $(XEN_ROOT)/tools/xenstore/Makefile.common +xenstorepvh/stamp: $(XEN_ROOT)/tools/xenstored/Makefile.common $(do_links) LINK_DIRS := xenstore xenstorepvh $(foreach dir,$(STUB_LIBS),libs-$(XEN_TARGET_ARCH)/$(dir)) diff --git a/tools/Makefile b/tools/Makefile index 311a9098d7..3a510663a0 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -8,7 +8,8 @@ SUBDIRS-y := SUBDIRS-y += libs SUBDIRS-y += flask SUBDIRS-y += fuzz -SUBDIRS-y += xenstore +SUBDIRS-y += xs-clients +SUBDIRS-$(XENSTORE_XENSTORED) += xenstored SUBDIRS-y += misc SUBDIRS-y += examples SUBDIRS-y += hotplug diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile deleted file mode 100644 index dc39b6cb31..0000000000 --- a/tools/xenstore/Makefile +++ /dev/null @@ -1,101 +0,0 @@ -XEN_ROOT=$(CURDIR)/../.. -include $(XEN_ROOT)/tools/Rules.mk - -include Makefile.common - -xenstored: LDLIBS += $(LDLIBS_libxenevtchn) -xenstored: LDLIBS += $(LDLIBS_libxengnttab) -xenstored: LDLIBS += $(LDLIBS_libxenctrl) -xenstored: LDLIBS += -lrt -xenstored: LDLIBS += $(SOCKET_LIBS) - -ifeq ($(CONFIG_SYSTEMD),y) -$(XENSTORED_OBJS-y): CFLAGS += $(SYSTEMD_CFLAGS) -xenstored: LDLIBS += $(SYSTEMD_LIBS) -endif - -xenstore: LDLIBS += $(LDLIBS_libxenstore) -xenstore: LDLIBS += $(LDLIBS_libxentoolcore) -xenstore: LDLIBS += $(SOCKET_LIBS) - -xenstore-control: LDLIBS += $(LDLIBS_libxenstore) -xenstore-control: LDLIBS += $(LDLIBS_libxenctrl) -xenstore-control: LDLIBS += $(LDLIBS_libxenguest) -xenstore-control: LDLIBS += $(LDLIBS_libxentoolcore) -xenstore-control: LDLIBS += $(SOCKET_LIBS) - -CLIENTS := xenstore-exists xenstore-list xenstore-read xenstore-rm xenstore-chmod -CLIENTS += xenstore-write xenstore-ls xenstore-watch - -TARGETS := xenstore $(CLIENTS) xenstore-control -ifeq ($(XENSTORE_XENSTORED),y) -TARGETS += xenstored -endif - -.PHONY: all -all: $(TARGETS) - -.PHONY: clients -clients: xenstore $(CLIENTS) xenstore-control - -xenstored: $(XENSTORED_OBJS-y) - $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(APPEND_LDFLAGS) - -$(CLIENTS): xenstore - ln -f xenstore $@ - -xenstore: xenstore_client.o - $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(APPEND_LDFLAGS) - -xenstore-control: xenstore_control.o - $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(APPEND_LDFLAGS) - -.PHONY: clean -clean:: - $(RM) $(TARGETS) $(DEPS_RM) - -.PHONY: distclean -distclean: clean - -.PHONY: TAGS -TAGS: - etags `find . -name '*.[ch]'` - -.PHONY: install -install: all - $(INSTALL_DIR) $(DESTDIR)$(bindir) -ifeq ($(XENSTORE_XENSTORED),y) - $(INSTALL_DIR) $(DESTDIR)$(sbindir) - $(INSTALL_PROG) xenstored $(DESTDIR)$(sbindir) -endif - $(INSTALL_PROG) xenstore-control $(DESTDIR)$(bindir) - $(INSTALL_PROG) xenstore $(DESTDIR)$(bindir) - set -e ; for c in $(CLIENTS) ; do \ - ln -f $(DESTDIR)$(bindir)/xenstore $(DESTDIR)$(bindir)/$${c} ; \ - done - -.PHONY: uninstall -uninstall: - rm -f $(addprefix $(DESTDIR)$(bindir)/, $(CLIENTS)) - rm -f $(DESTDIR)$(bindir)/xenstore - rm -f $(DESTDIR)$(bindir)/xenstore-control -ifeq ($(XENSTORE_XENSTORED),y) - rm -f $(DESTDIR)$(sbindir)/xenstored -endif - if [ -d $(DESTDIR)$(includedir)/xenstore-compat ]; then \ - rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/xenstore-compat; \ - fi - -.PHONY: clients-uninstall -clients-uninstall: - rm -f $(addprefix $(DESTDIR)$(bindir)/, $(CLIENTS)) - -.PHONY: clients-install -clients-install: clients - $(INSTALL_DIR) $(DESTDIR)$(bindir) - $(INSTALL_PROG) xenstore $(DESTDIR)$(bindir) - set -e ; for c in $(CLIENTS) ; do \ - ln -f $(DESTDIR)$(bindir)/xenstore $(DESTDIR)$(bindir)/$${c} ; \ - done - --include $(DEPS_INCLUDE) diff --git a/tools/xenstore/Makefile.common b/tools/xenstore/Makefile.common deleted file mode 100644 index 41973a8a5e..0000000000 --- a/tools/xenstore/Makefile.common +++ /dev/null @@ -1,30 +0,0 @@ -# Makefile shared with stubdom - -XENSTORED_OBJS-y := xenstored_core.o xenstored_watch.o xenstored_domain.o -XENSTORED_OBJS-y += xenstored_transaction.o xenstored_control.o xenstored_lu.o -XENSTORED_OBJS-y += talloc.o utils.o hashtable.o - -XENSTORED_OBJS-$(CONFIG_Linux) += xenstored_posix.o xenstored_lu_daemon.o -XENSTORED_OBJS-$(CONFIG_NetBSD) += xenstored_posix.o xenstored_lu_daemon.o -XENSTORED_OBJS-$(CONFIG_FreeBSD) += xenstored_posix.o xenstored_lu_daemon.o -XENSTORED_OBJS-$(CONFIG_MiniOS) += xenstored_minios.o xenstored_lu_minios.o - -# Include configure output (config.h) -CFLAGS += -include $(XEN_ROOT)/tools/config.h -CFLAGS += -I./include -CFLAGS += $(CFLAGS_libxenevtchn) -CFLAGS += $(CFLAGS_libxenctrl) -CFLAGS += $(CFLAGS_libxenguest) -CFLAGS += $(CFLAGS_libxentoolcore) - -ifdef CONFIG_STUBDOM -CFLAGS += -DNO_SOCKETS=1 -endif - -$(XENSTORED_OBJS-y): CFLAGS += $(CFLAGS_libxengnttab) - -xenstored.a: $(XENSTORED_OBJS-y) - $(AR) cr $@ $^ - -clean:: - $(RM) *.a *.o diff --git a/tools/xenstore/README b/tools/xenstore/README deleted file mode 100644 index 7c1ff6d43e..0000000000 --- a/tools/xenstore/README +++ /dev/null @@ -1,5 +0,0 @@ -The following files are imported from the Samba project. We use the versions -from Samba 3, the current stable branch. - -talloc.c: samba-trunk/source/lib/talloc.c r14291 2006-03-13 04:27:47 +0000 -talloc.h: samba-trunk/source/include/talloc.h r11986 2005-12-01 00:43:36 +0000 diff --git a/tools/xenstore/hashtable.c b/tools/xenstore/hashtable.c deleted file mode 100644 index 0c26a09567..0000000000 --- a/tools/xenstore/hashtable.c +++ /dev/null @@ -1,316 +0,0 @@ -/* Copyright (C) 2004 Christopher Clark <firstname.lastname@xxxxxxxxxxxx> */ - -#include "hashtable.h" -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <math.h> -#include <stdint.h> -#include <stdarg.h> -#include "talloc.h" - -struct entry -{ - const void *k; - void *v; - unsigned int h; - struct entry *next; -}; - -struct hashtable { - unsigned int tablelength; - unsigned int flags; - struct entry **table; - unsigned int entrycount; - unsigned int loadlimit; - unsigned int primeindex; - unsigned int (*hashfn) (const void *k); - int (*eqfn) (const void *k1, const void *k2); -}; - -/* - * Credit for primes table: Aaron Krowne - * https://planetmath.org/goodhashtableprimes - */ -static const unsigned int primes[] = { -11, 23, 53, 97, 193, 389, -769, 1543, 3079, 6151, -12289, 24593, 49157, 98317, -196613, 393241, 786433, 1572869, -3145739, 6291469, 12582917, 25165843, -50331653, 100663319, 201326611, 402653189, -805306457, 1610612741 -}; - -#define PRIME_TABLE_LEN ARRAY_SIZE(primes) -#define MAX_LOAD_PERCENT 65 - -static inline unsigned int indexFor(unsigned int tablelength, - unsigned int hashvalue) -{ - return (hashvalue % tablelength); -} - -static unsigned int loadlimit(unsigned int pindex) -{ - return ((uint64_t)primes[pindex] * MAX_LOAD_PERCENT) / 100; -} - -struct hashtable *create_hashtable(const void *ctx, const char *name, - unsigned int (*hashf) (const void *), - int (*eqf) (const void *, const void *), - unsigned int flags) -{ - struct hashtable *h; - - h = talloc_zero(ctx, struct hashtable); - if (NULL == h) - goto err0; - talloc_set_name_const(h, name); - h->table = talloc_zero_array(h, struct entry *, primes[0]); - if (NULL == h->table) - goto err1; - - h->primeindex = 0; - h->tablelength = primes[h->primeindex]; - h->flags = flags; - h->entrycount = 0; - h->hashfn = hashf; - h->eqfn = eqf; - h->loadlimit = loadlimit(h->primeindex); - return h; - -err1: - talloc_free(h); -err0: - return NULL; -} - -static unsigned int hash(const struct hashtable *h, const void *k) -{ - /* Aim to protect against poor hash functions by adding logic here - * - logic taken from java 1.4 hashtable source */ - unsigned int i = h->hashfn(k); - i += ~(i << 9); - i ^= ((i >> 14) | (i << 18)); /* >>> */ - i += (i << 4); - i ^= ((i >> 10) | (i << 22)); /* >>> */ - return i; -} - -static int hashtable_expand(struct hashtable *h) -{ - /* Double the size of the table to accomodate more entries */ - struct entry **newtable; - struct entry *e; - struct entry **pE; - unsigned int newsize, i, index; - /* Check we're not hitting max capacity */ - if (h->primeindex == (PRIME_TABLE_LEN - 1)) - return ENOSPC; - newsize = primes[++(h->primeindex)]; - - newtable = talloc_realloc(h, h->table, struct entry *, newsize); - if (!newtable) - { - h->primeindex--; - return ENOMEM; - } - - h->table = newtable; - memset(newtable + h->tablelength, 0, - (newsize - h->tablelength) * sizeof(*newtable)); - for (i = 0; i < h->tablelength; i++) { - for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) { - index = indexFor(newsize, e->h); - if (index == i) - { - pE = &(e->next); - } - else - { - *pE = e->next; - e->next = newtable[index]; - newtable[index] = e; - } - } - } - - h->tablelength = newsize; - h->loadlimit = loadlimit(h->primeindex); - return 0; -} - -static struct entry *hashtable_search_entry(const struct hashtable *h, - const void *k) -{ - struct entry *e; - unsigned int hashvalue, index; - - hashvalue = hash(h, k); - index = indexFor(h->tablelength, hashvalue); - e = h->table[index]; - - for (e = h->table[index]; e; e = e->next) - { - /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) - return e; - } - - return NULL; -} - -int hashtable_add(struct hashtable *h, const void *k, void *v) -{ - unsigned int index; - struct entry *e; - - if (hashtable_search_entry(h, k)) - return EEXIST; - - if (++(h->entrycount) > h->loadlimit) - { - /* Ignore the return value. If expand fails, we should - * still try cramming just this value into the existing table - * -- we may not have memory for a larger table, but one more - * element may be ok. Next time we insert, we'll try expanding again.*/ - hashtable_expand(h); - } - e = talloc_zero(h, struct entry); - if (NULL == e) - { - --h->entrycount; - return ENOMEM; - } - e->h = hash(h,k); - index = indexFor(h->tablelength,e->h); - e->k = k; - if (h->flags & HASHTABLE_FREE_KEY) - talloc_steal(e, k); - e->v = v; - if (h->flags & HASHTABLE_FREE_VALUE) - talloc_steal(e, v); - e->next = h->table[index]; - h->table[index] = e; - return 0; -} - -void *hashtable_search(const struct hashtable *h, const void *k) -{ - struct entry *e; - - e = hashtable_search_entry(h, k); - - return e ? e->v : NULL; -} - -int hashtable_replace(struct hashtable *h, const void *k, void *v) -{ - struct entry *e; - - e = hashtable_search_entry(h, k); - if (!e) - return ENOENT; - - if (h->flags & HASHTABLE_FREE_VALUE) - { - talloc_free(e->v); - talloc_steal(e, v); - } - - e->v = v; - - return 0; -} - -void -hashtable_remove(struct hashtable *h, const void *k) -{ - /* TODO: consider compacting the table when the load factor drops enough, - * or provide a 'compact' method. */ - - struct entry *e; - struct entry **pE; - unsigned int hashvalue, index; - - hashvalue = hash(h,k); - index = indexFor(h->tablelength,hash(h,k)); - pE = &(h->table[index]); - e = *pE; - while (NULL != e) - { - /* Check hash value to short circuit heavier comparison */ - if ((hashvalue == e->h) && (h->eqfn(k, e->k))) - { - *pE = e->next; - h->entrycount--; - talloc_free(e); - return; - } - pE = &(e->next); - e = e->next; - } -} - -int hashtable_iterate(struct hashtable *h, - int (*func)(const void *k, void *v, void *arg), void *arg) -{ - int ret; - unsigned int i; - struct entry *e, *f; - struct entry **table = h->table; - - for (i = 0; i < h->tablelength; i++) - { - e = table[i]; - while (e) - { - f = e; - e = e->next; - ret = func(f->k, f->v, arg); - if (ret) - return ret; - } - } - - return 0; -} - -void hashtable_destroy(struct hashtable *h) -{ - talloc_free(h); -} - -/* - * Copyright (c) 2002, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ diff --git a/tools/xenstore/hashtable.h b/tools/xenstore/hashtable.h deleted file mode 100644 index 336540413b..0000000000 --- a/tools/xenstore/hashtable.h +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright (C) 2002 Christopher Clark <firstname.lastname@xxxxxxxxxxxx> */ - -#ifndef __HASHTABLE_CWC22_H__ -#define __HASHTABLE_CWC22_H__ - -struct hashtable; - -/***************************************************************************** - * create_hashtable - - * @name create_hashtable - * @param ctx talloc context to use for allocations - * @param name talloc name of the hashtable - * @param hashfunction function for hashing keys - * @param key_eq_fn function for determining key equality - * @param flags flags HASHTABLE_* - * @return newly created hashtable or NULL on failure - */ - -/* Let hashtable_destroy() free the entries' values. */ -#define HASHTABLE_FREE_VALUE (1U << 0) -/* Let hashtable_remove() and hashtable_destroy() free the entries' keys. */ -#define HASHTABLE_FREE_KEY (1U << 1) - -struct hashtable * -create_hashtable(const void *ctx, const char *name, - unsigned int (*hashfunction) (const void *), - int (*key_eq_fn) (const void *, const void *), - unsigned int flags -); - -/***************************************************************************** - * hashtable_add - - * @name hashtable_add - * @param h the hashtable to insert into - * @param k the key - hashtable claims ownership and will free on removal - * @param v the value - does not claim ownership - * @return zero for successful insertion - * - * This function will cause the table to expand if the insertion would take - * the ratio of entries to table size over the maximum load factor. - */ - -int -hashtable_add(struct hashtable *h, const void *k, void *v); - -/***************************************************************************** - * hashtable_replace - - * @name hashtable_nsert - * @param h the hashtable to insert into - * @param k the key - hashtable claims ownership and will free on removal - * @param v the value - does not claim ownership - * @return zero for successful insertion - * - * This function does check for an entry being present before replacing it - * with a new value. - */ - -int -hashtable_replace(struct hashtable *h, const void *k, void *v); - -/***************************************************************************** - * hashtable_search - - * @name hashtable_search - * @param h the hashtable to search - * @param k the key to search for - does not claim ownership - * @return the value associated with the key, or NULL if none found - */ - -void * -hashtable_search(const struct hashtable *h, const void *k); - -/***************************************************************************** - * hashtable_remove - - * @name hashtable_remove - * @param h the hashtable to remove the item from - * @param k the key to search for - does not claim ownership - */ - -void -hashtable_remove(struct hashtable *h, const void *k); - -/***************************************************************************** - * hashtable_iterate - - * @name hashtable_iterate - * @param h the hashtable - * @param func function to call for each entry - * @param arg user supplied parameter for func - * @return 0 if okay, non-zero return value of func (and iteration - * was aborted) - * - * Iterates over all entries in the hashtable and calls func with the - * key, value, and the user supplied parameter. - * func returning a non-zero value will abort the iteration. In case func is - * removing an entry other than itself from the hashtable, it must return a - * non-zero value in order to abort the iteration. Inserting entries is - * allowed, but it is undefined whether func will be called for those new - * entries during this iteration. - */ -int -hashtable_iterate(struct hashtable *h, - int (*func)(const void *k, void *v, void *arg), void *arg); - -/***************************************************************************** - * hashtable_destroy - - * @name hashtable_destroy - * @param h the hashtable - */ - -void -hashtable_destroy(struct hashtable *h); - -#endif /* __HASHTABLE_CWC22_H__ */ - -/* - * Copyright (c) 2002, Christopher Clark - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of the original author; nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ diff --git a/tools/xenstore/include/xenstore_state.h b/tools/xenstore/include/xenstore_state.h deleted file mode 100644 index ae0d053c8f..0000000000 --- a/tools/xenstore/include/xenstore_state.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Xenstore internal state dump definitions. - * Copyright (C) Juergen Gross, SUSE Software Solutions Germany GmbH - * - * Used for live-update and migration, possibly across Xenstore implementations. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef XENSTORE_STATE_H -#define XENSTORE_STATE_H - -#include INCLUDE_ENDIAN_H -#include <sys/types.h> - -#ifndef htobe32 -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define htobe32(x) __builtin_bswap32(x) -#else -#define htobe32(x) (x) -#endif -#endif - -struct xs_state_preamble { - char ident[8]; -#define XS_STATE_IDENT "xenstore" /* To be used without the NUL byte. */ - uint32_t version; /* Version in big endian format. */ -#define XS_STATE_VERSION 0x00000001 - uint32_t flags; /* Endianess. */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define XS_STATE_FLAGS 0x00000000 /* Little endian. */ -#else -#define XS_STATE_FLAGS 0x00000001 /* Big endian. */ -#endif -}; - -/* - * Each record is starting with xs_state_record_header. - * All records have a length of a multiple of 8 bytes. - */ - -/* Common record layout: */ -struct xs_state_record_header { - uint32_t type; -#define XS_STATE_TYPE_END 0x00000000 -#define XS_STATE_TYPE_GLOBAL 0x00000001 -#define XS_STATE_TYPE_CONN 0x00000002 -#define XS_STATE_TYPE_WATCH 0x00000003 -#define XS_STATE_TYPE_TA 0x00000004 -#define XS_STATE_TYPE_NODE 0x00000005 - uint32_t length; /* Length of record in bytes. */ -}; - -/* Global state of Xenstore: */ -struct xs_state_global { - int32_t socket_fd; /* File descriptor for socket connections or -1. */ - int32_t evtchn_fd; /* File descriptor for event channel operations. */ -}; - -/* Connection to Xenstore: */ -struct xs_state_connection { - uint32_t conn_id; /* Used as reference in watch and TA records. */ - uint16_t conn_type; -#define XS_STATE_CONN_TYPE_RING 0 -#define XS_STATE_CONN_TYPE_SOCKET 1 - uint16_t pad; - union { - struct { - uint16_t domid; /* Domain-Id. */ - uint16_t tdomid; /* Id of target domain or DOMID_INVALID. */ - uint32_t evtchn; /* Event channel port. */ - } ring; - int32_t socket_fd; /* File descriptor for socket connections. */ - } spec; - uint16_t data_in_len; /* Number of unprocessed bytes read from conn. */ - uint16_t data_resp_len; /* Size of partial response pending for conn. */ - uint32_t data_out_len; /* Number of bytes not yet written to conn. */ - uint8_t data[]; /* Pending data (read, written) + 0-7 pad bytes. */ -}; - -/* Watch: */ -struct xs_state_watch { - uint32_t conn_id; /* Connection this watch is associated with. */ - uint16_t path_length; /* Number of bytes of path watched (incl. 0). */ - uint16_t token_length; /* Number of bytes of watch token (incl. 0). */ - uint8_t data[]; /* Path bytes, token bytes, 0-7 pad bytes. */ -}; - -/* Transaction: */ -struct xs_state_transaction { - uint32_t conn_id; /* Connection this TA is associated with. */ - uint32_t ta_id; /* Transaction Id. */ -}; - -/* Node (either XS_STATE_TYPE_NODE or XS_STATE_TYPE_TANODE[_MOD]): */ -struct xs_state_node_perm { - uint8_t access; /* Access rights. */ -#define XS_STATE_NODE_PERM_NONE 'n' -#define XS_STATE_NODE_PERM_READ 'r' -#define XS_STATE_NODE_PERM_WRITE 'w' -#define XS_STATE_NODE_PERM_BOTH 'b' - uint8_t flags; -#define XS_STATE_NODE_PERM_IGNORE 0x01 /* Stale permission, ignore for check. */ - uint16_t domid; /* Domain-Id. */ -}; -struct xs_state_node { - uint32_t conn_id; /* Connection in case of transaction or 0. */ - uint32_t ta_id; /* Transaction Id or 0. */ - uint16_t path_len; /* Length of path string including NUL byte. */ - uint16_t data_len; /* Length of node data. */ - uint16_t ta_access; -#define XS_STATE_NODE_TA_DELETED 0x0000 -#define XS_STATE_NODE_TA_READ 0x0001 -#define XS_STATE_NODE_TA_WRITTEN 0x0002 - uint16_t perm_n; /* Number of permissions (0 in TA: node deleted). */ - /* Permissions (first is owner, has full access). */ - struct xs_state_node_perm perms[]; - /* Path and data follows, plus 0-7 pad bytes. */ -}; -#endif /* XENSTORE_STATE_H */ diff --git a/tools/xenstore/list.h b/tools/xenstore/list.h deleted file mode 100644 index d722a91220..0000000000 --- a/tools/xenstore/list.h +++ /dev/null @@ -1,283 +0,0 @@ -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H -/* Taken from Linux kernel code, but de-kernelized for userspace. */ -#include <stddef.h> - -#include <xen-tools/common-macros.h> - -#undef LIST_HEAD_INIT -#undef LIST_HEAD -#undef INIT_LIST_HEAD - -/* - * These are non-NULL pointers that will result in page faults - * under normal circumstances, used to verify that nobody uses - * non-initialized list entries. - */ -#define LIST_POISON1 ((void *) 0x00100100) -#define LIST_POISON2 ((void *) 0x00200200) - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -#define INIT_LIST_HEAD(ptr) do { \ - (ptr)->next = (ptr); (ptr)->prev = (ptr); \ -} while (0) - -#define list_top(head, type, member) \ -({ \ - struct list_head *_head = (head); \ - list_empty(_head) ? NULL : list_entry(_head->next, type, member); \ -}) - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head * prev, struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty on entry does not return true after this, the entry is - * in an undefined state. - */ -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = LIST_POISON1; - entry->prev = LIST_POISON2; -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(struct list_head *head) -{ - return head->next == head; -} - -static inline void __list_splice(struct list_head *list, - struct list_head *head) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(struct list_head *list, struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop counter. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - - -/** - * list_for_each_entry_continue - iterate over list of given type - * continuing after existing point - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -#endif diff --git a/tools/xenstore/talloc.c b/tools/xenstore/talloc.c deleted file mode 100644 index e42c7d4471..0000000000 --- a/tools/xenstore/talloc.c +++ /dev/null @@ -1,1323 +0,0 @@ -/* - Samba Unix SMB/CIFS implementation. - - Samba trivial allocation library - new interface - - NOTE: Please read talloc_guide.txt for full documentation - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; If not, see <http://www.gnu.org/licenses/>. -*/ - -/* - inspired by http://swapped.cc/halloc/ -*/ - -#ifdef _SAMBA_BUILD_ -#include "includes.h" -#if ((SAMBA_VERSION_MAJOR==3)&&(SAMBA_VERSION_MINOR<9)) -/* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file - * we trust ourselves... */ -#ifdef malloc -#undef malloc -#endif -#ifdef realloc -#undef realloc -#endif -#endif -#else -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <stdint.h> -#include "talloc.h" -/* assume a modern system */ -#define HAVE_VA_COPY -#endif - -/* use this to force every realloc to change the pointer, to stress test - code that might not cope */ -#define ALWAYS_REALLOC 0 - - -#define MAX_TALLOC_SIZE 0x10000000 -#define TALLOC_MAGIC 0xe814ec70 -#define TALLOC_FLAG_FREE 0x01 -#define TALLOC_FLAG_LOOP 0x02 -#define TALLOC_MAGIC_REFERENCE ((const char *)1) - -/* by default we abort when given a bad pointer (such as when talloc_free() is called - on a pointer that came from malloc() */ -#ifndef TALLOC_ABORT -#define TALLOC_ABORT(reason) abort() -#endif - -#ifndef discard_const_p -#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) -# define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr))) -#else -# define discard_const_p(type, ptr) ((type *)(ptr)) -#endif -#endif - -/* this null_context is only used if talloc_enable_leak_report() or - talloc_enable_leak_report_full() is called, otherwise it remains - NULL -*/ -static const void *null_context; -static void *cleanup_context; - - -struct talloc_reference_handle { - struct talloc_reference_handle *next, *prev; - void *ptr; -}; - -typedef int (*talloc_destructor_t)(void *); - -struct talloc_chunk { - struct talloc_chunk *next, *prev; - struct talloc_chunk *parent, *child; - struct talloc_reference_handle *refs; - unsigned int null_refs; /* references from null_context */ - talloc_destructor_t destructor; - const char *name; - size_t size; - unsigned flags; -}; - -/* 16 byte alignment seems to keep everyone happy */ -#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15) -#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc)) - -/* panic if we get a bad magic value */ -static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) -{ - const char *pp = ptr; - struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); - if ((tc->flags & ~0xF) != TALLOC_MAGIC) { - TALLOC_ABORT("Bad talloc magic value - unknown value"); - } - if (tc->flags & TALLOC_FLAG_FREE) { - TALLOC_ABORT("Bad talloc magic value - double free"); - } - return tc; -} - -/* hook into the front of the list */ -#define _TLIST_ADD(list, p) \ -do { \ - if (!(list)) { \ - (list) = (p); \ - (p)->next = (p)->prev = NULL; \ - } else { \ - (list)->prev = (p); \ - (p)->next = (list); \ - (p)->prev = NULL; \ - (list) = (p); \ - }\ -} while (0) - -/* remove an element from a list - element doesn't have to be in list. */ -#define _TLIST_REMOVE(list, p) \ -do { \ - if ((p) == (list)) { \ - (list) = (p)->next; \ - if (list) (list)->prev = NULL; \ - } else { \ - if ((p)->prev) (p)->prev->next = (p)->next; \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - } \ - if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \ -} while (0) - - -/* - return the parent chunk of a pointer -*/ -static struct talloc_chunk *talloc_parent_chunk(const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - while (tc->prev) tc=tc->prev; - return tc->parent; -} - -void *talloc_parent(const void *ptr) -{ - struct talloc_chunk *tc = talloc_parent_chunk(ptr); - return tc? TC_PTR_FROM_CHUNK(tc) : NULL; -} - -/* - Allocate a bit of memory as a child of an existing pointer -*/ -void *_talloc(const void *context, size_t size) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - context = null_context; - } - - if (size >= MAX_TALLOC_SIZE) { - return NULL; - } - - tc = malloc(TC_HDR_SIZE+size); - if (tc == NULL) return NULL; - - tc->size = size; - tc->flags = TALLOC_MAGIC; - tc->destructor = NULL; - tc->child = NULL; - tc->name = NULL; - tc->refs = NULL; - tc->null_refs = 0; - - if (context) { - struct talloc_chunk *parent = talloc_chunk_from_ptr(context); - - tc->parent = parent; - - if (parent->child) { - parent->child->parent = NULL; - } - - _TLIST_ADD(parent->child, tc); - } else { - tc->next = tc->prev = tc->parent = NULL; - } - - return TC_PTR_FROM_CHUNK(tc); -} - - -/* - setup a destructor to be called on free of a pointer - the destructor should return 0 on success, or -1 on failure. - if the destructor fails then the free is failed, and the memory can - be continued to be used -*/ -void talloc_set_destructor(const void *ptr, int (*destructor)(void *)) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - tc->destructor = destructor; -} - -/* - increase the reference count on a piece of memory. -*/ -void talloc_increase_ref_count(const void *ptr) -{ - struct talloc_chunk *tc; - if (ptr == NULL) return; - - tc = talloc_chunk_from_ptr(ptr); - tc->null_refs++; -} - -/* - helper for talloc_reference() -*/ -static int talloc_reference_destructor(void *ptr) -{ - struct talloc_reference_handle *handle = ptr; - struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr); - struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr); - if (tc1->destructor != (talloc_destructor_t)-1) { - tc1->destructor = NULL; - } - _TLIST_REMOVE(tc2->refs, handle); - talloc_free(handle); - return 0; -} - -/* - make a secondary reference to a pointer, hanging off the given context. - the pointer remains valid until both the original caller and this given - context are freed. - - the major use for this is when two different structures need to reference the - same underlying data, and you want to be able to free the two instances separately, - and in either order -*/ -void *talloc_reference(const void *context, const void *ptr) -{ - struct talloc_chunk *tc; - struct talloc_reference_handle *handle; - if (ptr == NULL) return NULL; - - tc = talloc_chunk_from_ptr(ptr); - handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE); - - if (handle == NULL) return NULL; - - /* note that we hang the destructor off the handle, not the - main context as that allows the caller to still setup their - own destructor on the context if they want to */ - talloc_set_destructor(handle, talloc_reference_destructor); - handle->ptr = discard_const_p(void, ptr); - _TLIST_ADD(tc->refs, handle); - return handle->ptr; -} - -/* - remove a secondary reference to a pointer. This undo's what - talloc_reference() has done. The context and pointer arguments - must match those given to a talloc_reference() -*/ -static int talloc_unreference(const void *context, const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - struct talloc_reference_handle *h; - - if (context == NULL) { - context = null_context; - } - - if ((context == null_context) && tc->null_refs) { - tc->null_refs--; - return 0; - } - - for (h=tc->refs;h;h=h->next) { - struct talloc_chunk *p = talloc_parent_chunk(h); - if (p == NULL) { - if (context == NULL) break; - } else if (TC_PTR_FROM_CHUNK(p) == context) { - break; - } - } - if (h == NULL) { - return -1; - } - - talloc_set_destructor(h, NULL); - _TLIST_REMOVE(tc->refs, h); - talloc_free(h); - return 0; -} - -/* - remove a specific parent context from a pointer. This is a more - controlled varient of talloc_free() -*/ -int talloc_unlink(const void *context, const void *ptr) -{ - struct talloc_chunk *tc_p, *new_p; - void *new_parent; - - if (ptr == NULL) { - return -1; - } - - if (context == NULL) { - context = null_context; - } - - if (talloc_unreference(context, ptr) == 0) { - return 0; - } - - if (context == NULL) { - if (talloc_parent_chunk(ptr) != NULL) { - return -1; - } - } else { - if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) { - return -1; - } - } - - tc_p = talloc_chunk_from_ptr(ptr); - - if (tc_p->refs == NULL) { - return talloc_free(ptr); - } - - new_p = talloc_parent_chunk(tc_p->refs); - if (new_p) { - new_parent = TC_PTR_FROM_CHUNK(new_p); - } else { - new_parent = NULL; - } - - if (talloc_unreference(new_parent, ptr) != 0) { - return -1; - } - - talloc_steal(new_parent, ptr); - - return 0; -} - -/* - add a name to an existing pointer - va_list version -*/ -static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); - -static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - tc->name = talloc_vasprintf(ptr, fmt, ap); - if (tc->name) { - talloc_set_name_const(tc->name, ".name"); - } -} - -/* - add a name to an existing pointer -*/ -void talloc_set_name(const void *ptr, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - talloc_set_name_v(ptr, fmt, ap); - va_end(ap); -} - -/* - more efficient way to add a name to a pointer - the name must point to a - true string constant -*/ -void talloc_set_name_const(const void *ptr, const char *name) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - tc->name = name; -} - -/* - create a named talloc pointer. Any talloc pointer can be named, and - talloc_named() operates just like talloc() except that it allows you - to name the pointer. -*/ -void *talloc_named(const void *context, size_t size, const char *fmt, ...) -{ - va_list ap; - void *ptr; - - ptr = _talloc(context, size); - if (ptr == NULL) return NULL; - - va_start(ap, fmt); - talloc_set_name_v(ptr, fmt, ap); - va_end(ap); - - return ptr; -} - -/* - create a named talloc pointer. Any talloc pointer can be named, and - talloc_named() operates just like talloc() except that it allows you - to name the pointer. -*/ -void *talloc_named_const(const void *context, size_t size, const char *name) -{ - void *ptr; - - ptr = _talloc(context, size); - if (ptr == NULL) { - return NULL; - } - - talloc_set_name_const(ptr, name); - - return ptr; -} - -/* - return the name of a talloc ptr, or "UNNAMED" -*/ -const char *talloc_get_name(const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - if (tc->name == TALLOC_MAGIC_REFERENCE) { - return ".reference"; - } - if (tc->name) { - return tc->name; - } - return "UNNAMED"; -} - - -/* - check if a pointer has the given name. If it does, return the pointer, - otherwise return NULL -*/ -void *talloc_check_name(const void *ptr, const char *name) -{ - const char *pname; - if (ptr == NULL) return NULL; - pname = talloc_get_name(ptr); - if (pname == name || strcmp(pname, name) == 0) { - return discard_const_p(void, ptr); - } - return NULL; -} - - -/* - this is for compatibility with older versions of talloc -*/ -void *talloc_init(const char *fmt, ...) -{ - va_list ap; - void *ptr; - - talloc_enable_null_tracking(); - - ptr = _talloc(NULL, 0); - if (ptr == NULL) return NULL; - - va_start(ap, fmt); - talloc_set_name_v(ptr, fmt, ap); - va_end(ap); - - return ptr; -} - -/* - this is a replacement for the Samba3 talloc_destroy_pool functionality. It - should probably not be used in new code. It's in here to keep the talloc - code consistent across Samba 3 and 4. -*/ -static void talloc_free_children(const void *ptr) -{ - struct talloc_chunk *tc; - - if (ptr == NULL) { - return; - } - - tc = talloc_chunk_from_ptr(ptr); - - while (tc->child) { - /* we need to work out who will own an abandoned child - if it cannot be freed. In priority order, the first - choice is owner of any remaining reference to this - pointer, the second choice is our parent, and the - final choice is the null context. */ - void *child = TC_PTR_FROM_CHUNK(tc->child); - const void *new_parent = null_context; - if (tc->child->refs) { - struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); - if (p) new_parent = TC_PTR_FROM_CHUNK(p); - } - if (talloc_free(child) == -1) { - if (new_parent == null_context) { - struct talloc_chunk *p = talloc_parent_chunk(ptr); - if (p) new_parent = TC_PTR_FROM_CHUNK(p); - } - talloc_steal(new_parent, child); - } - } -} - -/* - free a talloc pointer. This also frees all child pointers of this - pointer recursively - - return 0 if the memory is actually freed, otherwise -1. The memory - will not be freed if the ref_count is > 1 or the destructor (if - any) returns non-zero -*/ -int talloc_free(const void *ptr) -{ - int saved_errno = errno; - struct talloc_chunk *tc; - - if (ptr == NULL) { - goto err; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (tc->null_refs) { - tc->null_refs--; - goto err; - } - - if (tc->refs) { - talloc_reference_destructor(tc->refs); - goto err; - } - - if (tc->flags & TALLOC_FLAG_LOOP) { - /* we have a free loop - stop looping */ - goto success; - } - - if (tc->destructor) { - talloc_destructor_t d = tc->destructor; - if (d == (talloc_destructor_t)-1) { - goto err; - } - tc->destructor = (talloc_destructor_t)-1; - - /* The destructor needs to be able to change the object! */ - if (d((void *)ptr) == -1) { - tc->destructor = d; - goto err; - } - tc->destructor = NULL; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - talloc_free_children(ptr); - - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - - tc->flags |= TALLOC_FLAG_FREE; - - free(tc); - success: - errno = saved_errno; - return 0; - - err: - errno = saved_errno; - return -1; -} - -/* - A talloc version of realloc. The context argument is only used if - ptr is NULL -*/ -void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name) -{ - struct talloc_chunk *tc; - void *new_ptr; - - /* size zero is equivalent to free() */ - if (size == 0) { - talloc_free(ptr); - return NULL; - } - - if (size >= MAX_TALLOC_SIZE) { - return NULL; - } - - /* realloc(NULL) is equavalent to malloc() */ - if (ptr == NULL) { - return talloc_named_const(context, size, name); - } - - tc = talloc_chunk_from_ptr(ptr); - - /* don't allow realloc on referenced pointers */ - if (tc->refs) { - return NULL; - } - - /* by resetting magic we catch users of the old memory */ - tc->flags |= TALLOC_FLAG_FREE; - -#if ALWAYS_REALLOC - new_ptr = malloc(size + TC_HDR_SIZE); - if (new_ptr) { - memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE); - free(tc); - } -#else - new_ptr = realloc(tc, size + TC_HDR_SIZE); -#endif - if (!new_ptr) { - tc->flags &= ~TALLOC_FLAG_FREE; - return NULL; - } - - tc = new_ptr; - tc->flags &= ~TALLOC_FLAG_FREE; - if (tc->parent) { - tc->parent->child = new_ptr; - } - if (tc->child) { - tc->child->parent = new_ptr; - } - - if (tc->prev) { - tc->prev->next = tc; - } - if (tc->next) { - tc->next->prev = tc; - } - - tc->size = size; - talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); - - return TC_PTR_FROM_CHUNK(tc); -} - -/* - move a lump of memory from one talloc context to another return the - ptr on success, or NULL if it could not be transferred. - passing NULL as ptr will always return NULL with no side effects. -*/ -void *talloc_steal(const void *new_ctx, const void *ptr) -{ - struct talloc_chunk *tc, *new_tc; - - if (!ptr) { - return NULL; - } - - if (new_ctx == NULL) { - new_ctx = null_context; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (new_ctx == NULL) { - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - - tc->parent = tc->next = tc->prev = NULL; - return discard_const_p(void, ptr); - } - - new_tc = talloc_chunk_from_ptr(new_ctx); - - if (tc == new_tc) { - return discard_const_p(void, ptr); - } - - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - - tc->parent = new_tc; - if (new_tc->child) new_tc->child->parent = NULL; - _TLIST_ADD(new_tc->child, tc); - - return discard_const_p(void, ptr); -} - -/* - return the total size of a talloc pool (subtree) -*/ -off_t talloc_total_size(const void *ptr) -{ - off_t total = 0; - struct talloc_chunk *c, *tc; - - if (ptr == NULL) { - ptr = null_context; - } - if (ptr == NULL) { - return 0; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return 0; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - total = tc->size; - for (c=tc->child;c;c=c->next) { - total += talloc_total_size(TC_PTR_FROM_CHUNK(c)); - } - - tc->flags &= ~TALLOC_FLAG_LOOP; - - return total; -} - -/* - return the total number of blocks in a talloc pool (subtree) -*/ -off_t talloc_total_blocks(const void *ptr) -{ - off_t total = 0; - struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return 0; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - total++; - for (c=tc->child;c;c=c->next) { - total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c)); - } - - tc->flags &= ~TALLOC_FLAG_LOOP; - - return total; -} - -/* - return the number of external references to a pointer -*/ -static int talloc_reference_count(const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - struct talloc_reference_handle *h; - int ret = 0; - - for (h=tc->refs;h;h=h->next) { - ret++; - } - return ret; -} - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -void talloc_report_depth(const void *ptr, FILE *f, int depth) -{ - struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - for (c=tc->child;c;c=c->next) { - if (c->name == TALLOC_MAGIC_REFERENCE) { - struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c); - const char *name2 = talloc_get_name(handle->ptr); - fprintf(f, "%*sreference to: %s\n", depth*4, "", name2); - } else { - const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c)); - fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", - depth*4, "", - name, - (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)), - (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)), - talloc_reference_count(TC_PTR_FROM_CHUNK(c))); - talloc_report_depth(TC_PTR_FROM_CHUNK(c), f, depth+1); - } - } - tc->flags &= ~TALLOC_FLAG_LOOP; -} - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -void talloc_report_full(const void *ptr, FILE *f) -{ - if (ptr == NULL) { - ptr = null_context; - } - if (ptr == NULL) return; - - fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n", - talloc_get_name(ptr), - (unsigned long)talloc_total_size(ptr), - (unsigned long)talloc_total_blocks(ptr)); - - talloc_report_depth(ptr, f, 1); - fflush(f); -} - -/* - report on memory usage by all children of a pointer -*/ -void talloc_report(const void *ptr, FILE *f) -{ - struct talloc_chunk *c, *tc; - - if (ptr == NULL) { - ptr = null_context; - } - if (ptr == NULL) return; - - fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n", - talloc_get_name(ptr), - (unsigned long)talloc_total_size(ptr), - (unsigned long)talloc_total_blocks(ptr)); - - tc = talloc_chunk_from_ptr(ptr); - - for (c=tc->child;c;c=c->next) { - fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n", - talloc_get_name(TC_PTR_FROM_CHUNK(c)), - (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)), - (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c))); - } - fflush(f); -} - -/* - report on any memory hanging off the null context -*/ -static void talloc_report_null(void) -{ - if (talloc_total_size(null_context) != 0) { - talloc_report(null_context, stderr); - } -} - -/* - report on any memory hanging off the null context -*/ -static void talloc_report_null_full(void) -{ - if (talloc_total_size(null_context) != 0) { - talloc_report_full(null_context, stderr); - } -} - -/* - enable tracking of the NULL context -*/ -void talloc_enable_null_tracking(void) -{ - if (null_context == NULL) { - null_context = talloc_named_const(NULL, 0, "null_context"); - } -} - -#ifdef _SAMBA_BUILD_ -/* Ugly calls to Samba-specific sprintf_append... JRA. */ - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -static void talloc_report_depth_str(const void *ptr, char **pps, ssize_t *plen, size_t *pbuflen, int depth) -{ - struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - for (c=tc->child;c;c=c->next) { - if (c->name == TALLOC_MAGIC_REFERENCE) { - struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c); - const char *name2 = talloc_get_name(handle->ptr); - - sprintf_append(NULL, pps, plen, pbuflen, - "%*sreference to: %s\n", depth*4, "", name2); - - } else { - const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c)); - - sprintf_append(NULL, pps, plen, pbuflen, - "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", - depth*4, "", - name, - (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)), - (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)), - talloc_reference_count(TC_PTR_FROM_CHUNK(c))); - - talloc_report_depth_str(TC_PTR_FROM_CHUNK(c), pps, plen, pbuflen, depth+1); - } - } - tc->flags &= ~TALLOC_FLAG_LOOP; -} - -/* - report on memory usage by all children of a pointer -*/ -char *talloc_describe_all(void) -{ - ssize_t len = 0; - size_t buflen = 512; - char *s = NULL; - - if (null_context == NULL) { - return NULL; - } - - sprintf_append(NULL, &s, &len, &buflen, - "full talloc report on '%s' (total %lu bytes in %lu blocks)\n", - talloc_get_name(null_context), - (unsigned long)talloc_total_size(null_context), - (unsigned long)talloc_total_blocks(null_context)); - - if (!s) { - return NULL; - } - talloc_report_depth_str(null_context, &s, &len, &buflen, 1); - return s; -} -#endif - -/* - enable leak reporting on exit -*/ -void talloc_enable_leak_report(void) -{ - talloc_enable_null_tracking(); - atexit(talloc_report_null); -} - -/* - enable full leak reporting on exit -*/ -void talloc_enable_leak_report_full(void) -{ - talloc_enable_null_tracking(); - atexit(talloc_report_null_full); -} - -/* - talloc and zero memory. -*/ -void *_talloc_zero(const void *ctx, size_t size, const char *name) -{ - void *p = talloc_named_const(ctx, size, name); - - if (p) { - memset(p, '\0', size); - } - - return p; -} - - -/* - memdup with a talloc. -*/ -void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name) -{ - void *newp = talloc_named_const(t, size, name); - - if (newp) { - memcpy(newp, p, size); - } - - return newp; -} - -/* - strdup with a talloc -*/ -char *talloc_strdup(const void *t, const char *p) -{ - char *ret; - if (!p) { - return NULL; - } - ret = talloc_memdup(t, p, strlen(p) + 1); - if (ret) { - talloc_set_name_const(ret, ret); - } - return ret; -} - -/* - append to a talloced string -*/ -char *talloc_append_string(const void *t, char *orig, const char *append) -{ - char *ret; - size_t olen = strlen(orig); - size_t alenz; - - if (!append) - return orig; - - alenz = strlen(append) + 1; - - ret = talloc_realloc(t, orig, char, olen + alenz); - if (!ret) - return NULL; - - /* append the string with the trailing \0 */ - memcpy(&ret[olen], append, alenz); - - return ret; -} - -/* - strndup with a talloc -*/ -char *talloc_strndup(const void *t, const char *p, size_t n) -{ - size_t len; - char *ret; - - for (len=0; len<n && p[len]; len++) ; - - ret = _talloc(t, len + 1); - if (!ret) { return NULL; } - memcpy(ret, p, len); - ret[len] = 0; - talloc_set_name_const(ret, ret); - return ret; -} - -#ifndef VA_COPY -#ifdef HAVE_VA_COPY -#define VA_COPY(dest, src) va_copy(dest, src) -#elif defined(HAVE___VA_COPY) -#define VA_COPY(dest, src) __va_copy(dest, src) -#else -#define VA_COPY(dest, src) (dest) = (src) -#endif -#endif - -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) -{ - int len; - char *ret; - va_list ap2; - char c; - - VA_COPY(ap2, ap); - - /* this call looks strange, but it makes it work on older solaris boxes */ - if ((len = vsnprintf(&c, 1, fmt, ap2)) < 0) { - va_end(ap2); - return NULL; - } - va_end(ap2); - - ret = _talloc(t, len+1); - if (ret) { - VA_COPY(ap2, ap); - vsnprintf(ret, len+1, fmt, ap2); - va_end(ap2); - talloc_set_name_const(ret, ret); - } - - return ret; -} - - -/* - Perform string formatting, and return a pointer to newly allocated - memory holding the result, inside a memory pool. - */ -char *talloc_asprintf(const void *t, const char *fmt, ...) -{ - va_list ap; - char *ret; - - va_start(ap, fmt); - ret = talloc_vasprintf(t, fmt, ap); - va_end(ap); - return ret; -} - - -/** - * Realloc @p s to append the formatted result of @p fmt and @p ap, - * and return @p s, which may have moved. Good for gradually - * accumulating output into a string buffer. - **/ - -static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); - -static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) -{ - struct talloc_chunk *tc; - int len, s_len; - va_list ap2; - - if (s == NULL) { - return talloc_vasprintf(NULL, fmt, ap); - } - - tc = talloc_chunk_from_ptr(s); - - VA_COPY(ap2, ap); - - s_len = tc->size - 1; - if ((len = vsnprintf(NULL, 0, fmt, ap2)) <= 0) { - /* Either the vsnprintf failed or the format resulted in - * no characters being formatted. In the former case, we - * ought to return NULL, in the latter we ought to return - * the original string. Most current callers of this - * function expect it to never return NULL. - */ - va_end(ap2); - return s; - } - va_end(ap2); - - s = talloc_realloc(NULL, s, char, s_len + len+1); - if (!s) return NULL; - - VA_COPY(ap2, ap); - - vsnprintf(s+s_len, len+1, fmt, ap2); - va_end(ap2); - talloc_set_name_const(s, s); - - return s; -} - -/* - Realloc @p s to append the formatted result of @p fmt and return @p - s, which may have moved. Good for gradually accumulating output - into a string buffer. - */ -char *talloc_asprintf_append(char *s, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - s = talloc_vasprintf_append(s, fmt, ap); - va_end(ap); - return s; -} - -/* - alloc an array, checking for integer overflow in the array size -*/ -void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name) -{ - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - return talloc_named_const(ctx, el_size * count, name); -} - -/* - alloc an zero array, checking for integer overflow in the array size -*/ -void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name) -{ - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - return _talloc_zero(ctx, el_size * count, name); -} - - -/* - realloc an array, checking for integer overflow in the array size -*/ -void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name) -{ - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - return _talloc_realloc(ctx, ptr, el_size * count, name); -} - -/* - a function version of talloc_realloc(), so it can be passed as a function pointer - to libraries that want a realloc function (a realloc function encapsulates - all the basic capabilities of an allocation library, which is why this is useful) -*/ -void *talloc_realloc_fn(const void *context, void *ptr, size_t size) -{ - return _talloc_realloc(context, ptr, size, NULL); -} - - -static void talloc_autofree(void) -{ - talloc_free(cleanup_context); - cleanup_context = NULL; -} - -/* - return a context which will be auto-freed on exit - this is useful for reducing the noise in leak reports -*/ -void *talloc_autofree_context(void) -{ - if (cleanup_context == NULL) { - cleanup_context = talloc_named_const(NULL, 0, "autofree_context"); - atexit(talloc_autofree); - } - return cleanup_context; -} - -size_t talloc_get_size(const void *context) -{ - struct talloc_chunk *tc; - - if (context == NULL) - return 0; - - tc = talloc_chunk_from_ptr(context); - - return tc->size; -} - -/* - find a parent of this context that has the given name, if any -*/ -void *talloc_find_parent_byname(const void *context, const char *name) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - return NULL; - } - - tc = talloc_chunk_from_ptr(context); - while (tc) { - if (tc->name && strcmp(tc->name, name) == 0) { - return TC_PTR_FROM_CHUNK(tc); - } - while (tc && tc->prev) tc = tc->prev; - tc = tc->parent; - } - return NULL; -} - -/* - show the parentage of a context -*/ -void talloc_show_parents(const void *context, FILE *file) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - fprintf(file, "talloc no parents for NULL\n"); - return; - } - - tc = talloc_chunk_from_ptr(context); - fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context)); - while (tc) { - fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc))); - while (tc && tc->prev) tc = tc->prev; - tc = tc->parent; - } -} diff --git a/tools/xenstore/talloc.h b/tools/xenstore/talloc.h deleted file mode 100644 index 32cee63d4d..0000000000 --- a/tools/xenstore/talloc.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef _TALLOC_H_ -#define _TALLOC_H_ -/* - Unix SMB/CIFS implementation. - Samba temporary memory allocation functions - - Copyright (C) Andrew Tridgell 2004-2005 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <stdarg.h> -#include <sys/types.h> - -#include "utils.h" - -/* this is only needed for compatibility with the old talloc */ -typedef void TALLOC_CTX; - -/* - this uses a little trick to allow __LINE__ to be stringified -*/ -#define _STRING_LINE_(s) #s -#define _STRING_LINE2_(s) _STRING_LINE_(s) -#define __LINESTR__ _STRING_LINE2_(__LINE__) -#define __location__ __FILE__ ":" __LINESTR__ - -#ifndef TALLOC_DEPRECATED -#define TALLOC_DEPRECATED 0 -#endif - -/* useful macros for creating type checked pointers */ -#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) -#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__) - -#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__) - -#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) -#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) - -#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) -#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) -#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) - -#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) -#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) - -#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) - -#define malloc_p(type) (type *)malloc(sizeof(type)) -#define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count) -#define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count) - -#if 0 -/* Not correct for Samba3. */ -#define data_blob(ptr, size) data_blob_named(ptr, size, "DATA_BLOB: "__location__) -#define data_blob_talloc(ctx, ptr, size) data_blob_talloc_named(ctx, ptr, size, "DATA_BLOB: "__location__) -#define data_blob_dup_talloc(ctx, blob) data_blob_talloc_named(ctx, (blob)->data, (blob)->length, "DATA_BLOB: "__location__) -#endif - -#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type) -#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type) - -#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type) - - -#if TALLOC_DEPRECATED -#define talloc_zero_p(ctx, type) talloc_zero(ctx, type) -#define talloc_p(ctx, type) talloc(ctx, type) -#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count) -#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count) -#define talloc_destroy(ctx) talloc_free(ctx) -#endif - -/* The following definitions come from talloc.c */ -void *_talloc(const void *context, size_t size); -void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); -void talloc_increase_ref_count(const void *ptr); -void *talloc_reference(const void *context, const void *ptr); -int talloc_unlink(const void *context, const void *ptr); -void talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -void talloc_set_name_const(const void *ptr, const char *name); -void *talloc_named(const void *context, size_t size, - const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); -void *talloc_named_const(const void *context, size_t size, const char *name); -const char *talloc_get_name(const void *ptr); -void *talloc_check_name(const void *ptr, const char *name); -void talloc_report_depth(const void *ptr, FILE *f, int depth); -void *talloc_parent(const void *ptr); -void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); -int talloc_free(const void *ptr); -void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); -void *talloc_steal(const void *new_ctx, const void *ptr); -off_t talloc_total_size(const void *ptr); -off_t talloc_total_blocks(const void *ptr); -void talloc_report_full(const void *ptr, FILE *f); -void talloc_report(const void *ptr, FILE *f); -void talloc_enable_null_tracking(void); -void talloc_enable_leak_report(void); -void talloc_enable_leak_report_full(void); -void *_talloc_zero(const void *ctx, size_t size, const char *name); -void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); -char *talloc_strdup(const void *t, const char *p); -char *talloc_strndup(const void *t, const char *p, size_t n); -char *talloc_append_string(const void *t, char *orig, const char *append); -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); -char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -char *talloc_asprintf_append(char *s, - const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); -void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); -void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); -void *talloc_realloc_fn(const void *context, void *ptr, size_t size); -void *talloc_autofree_context(void); -size_t talloc_get_size(const void *ctx); -void *talloc_find_parent_byname(const void *ctx, const char *name); -void talloc_show_parents(const void *context, FILE *file); - -#endif - diff --git a/tools/xenstore/talloc_guide.txt b/tools/xenstore/talloc_guide.txt deleted file mode 100644 index c23ac77cad..0000000000 --- a/tools/xenstore/talloc_guide.txt +++ /dev/null @@ -1,569 +0,0 @@ -Using talloc in Samba4 ----------------------- - -Andrew Tridgell -September 2004 - -The most current version of this document is available at - http://samba.org/ftp/unpacked/samba4/source/lib/talloc/talloc_guide.txt - -If you are used to talloc from Samba3 then please read this carefully, -as talloc has changed a lot. - -The new talloc is a hierarchical, reference counted memory pool system -with destructors. Quite a mounthful really, but not too bad once you -get used to it. - -Perhaps the biggest change from Samba3 is that there is no distinction -between a "talloc context" and a "talloc pointer". Any pointer -returned from talloc() is itself a valid talloc context. This means -you can do this: - - struct foo *X = talloc(mem_ctx, struct foo); - X->name = talloc_strdup(X, "foo"); - -and the pointer X->name would be a "child" of the talloc context "X" -which is itself a child of mem_ctx. So if you do talloc_free(mem_ctx) -then it is all destroyed, whereas if you do talloc_free(X) then just X -and X->name are destroyed, and if you do talloc_free(X->name) then -just the name element of X is destroyed. - -If you think about this, then what this effectively gives you is an -n-ary tree, where you can free any part of the tree with -talloc_free(). - -If you find this confusing, then I suggest you run the testsuite to -watch talloc in action. You may also like to add your own tests to -testsuite.c to clarify how some particular situation is handled. - - -Performance ------------ - -All the additional features of talloc() over malloc() do come at a -price. We have a simple performance test in Samba4 that measures -talloc() versus malloc() performance, and it seems that talloc() is -about 10% slower than malloc() on my x86 Debian Linux box. For Samba, -the great reduction in code complexity that we get by using talloc -makes this worthwhile, especially as the total overhead of -talloc/malloc in Samba is already quite small. - - -talloc API ----------- - -The following is a complete guide to the talloc API. Read it all at -least twice. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc(const void *context, type); - -The talloc() macro is the core of the talloc library. It takes a -memory context and a type, and returns a pointer to a new area of -memory of the given type. - -The returned pointer is itself a talloc context, so you can use it as -the context argument to more calls to talloc if you wish. - -The returned pointer is a "child" of the supplied context. This means -that if you talloc_free() the context then the new child disappears as -well. Alternatively you can free just the child. - -The context argument to talloc() can be NULL, in which case a new top -level context is created. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_size(const void *context, size_t size); - -The function talloc_size() should be used when you don't have a -convenient type to pass to talloc(). Unlike talloc(), it is not type -safe (as it returns a void *), so you are on your own for type checking. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_free(void *ptr); - -The talloc_free() function frees a piece of talloc memory, and all its -children. You can call talloc_free() on any pointer returned by -talloc(). - -The return value of talloc_free() indicates success or failure, with 0 -returned for success and -1 for failure. The only possible failure -condition is if the pointer had a destructor attached to it and the -destructor returned -1. See talloc_set_destructor() for details on -destructors. - -If this pointer has an additional parent when talloc_free() is called -then the memory is not actually released, but instead the most -recently established parent is destroyed. See talloc_reference() for -details on establishing additional parents. - -For more control on which parent is removed, see talloc_unlink() - -talloc_free() operates recursively on its children. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_free_children(void *ptr); - -The talloc_free_children() walks along the list of all children of a -talloc context and talloc_free()s only the children, not the context -itself. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_reference(const void *context, const void *ptr); - -The talloc_reference() function makes "context" an additional parent -of "ptr". - -The return value of talloc_reference() is always the original pointer -"ptr", unless talloc ran out of memory in creating the reference in -which case it will return NULL (each additional reference consumes -around 48 bytes of memory on intel x86 platforms). - -If "ptr" is NULL, then the function is a no-op, and simply returns NULL. - -After creating a reference you can free it in one of the following -ways: - - - you can talloc_free() any parent of the original pointer. That - will reduce the number of parents of this pointer by 1, and will - cause this pointer to be freed if it runs out of parents. - - - you can talloc_free() the pointer itself. That will destroy the - most recently established parent to the pointer and leave the - pointer as a child of its current parent. - -For more control on which parent to remove, see talloc_unlink() - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_unlink(const void *context, const void *ptr); - -The talloc_unlink() function removes a specific parent from ptr. The -context passed must either be a context used in talloc_reference() -with this pointer, or must be a direct parent of ptr. - -Note that if the parent has already been removed using talloc_free() -then this function will fail and will return -1. Likewise, if "ptr" -is NULL, then the function will make no modifications and return -1. - -Usually you can just use talloc_free() instead of talloc_unlink(), but -sometimes it is useful to have the additional control on which parent -is removed. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); - -The function talloc_set_destructor() sets the "destructor" for the -pointer "ptr". A destructor is a function that is called when the -memory used by a pointer is about to be released. The destructor -receives the pointer as an argument, and should return 0 for success -and -1 for failure. - -The destructor can do anything it wants to, including freeing other -pieces of memory. A common use for destructors is to clean up -operating system resources (such as open file descriptors) contained -in the structure the destructor is placed on. - -You can only place one destructor on a pointer. If you need more than -one destructor then you can create a zero-length child of the pointer -and place an additional destructor on that. - -To remove a destructor call talloc_set_destructor() with NULL for the -destructor. - -If your destructor attempts to talloc_free() the pointer that it is -the destructor for then talloc_free() will return -1 and the free will -be ignored. This would be a pointless operation anyway, as the -destructor is only called when the memory is just about to go away. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_increase_ref_count(const void *ptr); - -The talloc_increase_ref_count(ptr) function is exactly equivalent to: - - talloc_reference(NULL, ptr); - -You can use either syntax, depending on which you think is clearer in -your code. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_name(const void *ptr, const char *fmt, ...); - -Each talloc pointer has a "name". The name is used principally for -debugging purposes, although it is also possible to set and get the -name on a pointer in as a way of "marking" pointers in your code. - -The main use for names on pointer is for "talloc reports". See -talloc_report() and talloc_report_full() for details. Also see -talloc_enable_leak_report() and talloc_enable_leak_report_full(). - -The talloc_set_name() function allocates memory as a child of the -pointer. It is logically equivalent to: - talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); - -Note that multiple calls to talloc_set_name() will allocate more -memory without releasing the name. All of the memory is released when -the ptr is freed using talloc_free(). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_name_const(const void *ptr, const char *name); - -The function talloc_set_name_const() is just like talloc_set_name(), -but it takes a string constant, and is much faster. It is extensively -used by the "auto naming" macros, such as talloc_p(). - -This function does not allocate any memory. It just copies the -supplied pointer into the internal representation of the talloc -ptr. This means you must not pass a name pointer to memory that will -disappear before the ptr is freed with talloc_free(). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_named(const void *context, size_t size, const char *fmt, ...); - -The talloc_named() function creates a named talloc pointer. It is -equivalent to: - - ptr = talloc_size(context, size); - talloc_set_name(ptr, fmt, ....); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_named_const(const void *context, size_t size, const char *name); - -This is equivalent to: - - ptr = talloc_size(context, size); - talloc_set_name_const(ptr, name); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const char *talloc_get_name(const void *ptr); - -This returns the current name for the given talloc pointer. See -talloc_set_name() for details. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_init(const char *fmt, ...); - -This function creates a zero length named talloc context as a top -level context. It is equivalent to: - - talloc_named(NULL, 0, fmt, ...); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_new(void *ctx); - -This is a utility macro that creates a new memory context hanging -off an exiting context, automatically naming it "talloc_new: __location__" -where __location__ is the source line it is called from. It is -particularly useful for creating a new temporary working context. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_realloc(const void *context, void *ptr, type, count); - -The talloc_realloc() macro changes the size of a talloc -pointer. The "count" argument is the number of elements of type "type" -that you want the resulting pointer to hold. - -talloc_realloc() has the following equivalences: - - talloc_realloc(context, NULL, type, 1) ==> talloc(context, type); - talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N); - talloc_realloc(context, ptr, type, 0) ==> talloc_free(ptr); - -The "context" argument is only used if "ptr" is not NULL, otherwise it -is ignored. - -talloc_realloc() returns the new pointer, or NULL on failure. The call -will fail either due to a lack of memory, or because the pointer has -more than one parent (see talloc_reference()). - -
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |