mirror of
				https://git.proxmox.com/git/mirror_zfs
				synced 2025-11-04 03:24:44 +00:00 
			
		
		
		
	Afterward, git grep ZoL matches: * README.md: * [ZoL Site](https://zfsonlinux.org) - Correct * etc/default/zfs.in:# ZoL userland configuration. - Changing this would induce a needless upgrade-check, if the user has modified the configuration; this can be updated the next time the defaults change * module/zfs/dmu_send.c: * ZoL < 0.7 does not handle [...] - Before 0.7 is ZoL, so fair enough Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz> Issue #11956
		
			
				
	
	
		
			248 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			248 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * This file is part of the ZFS Event Daemon (ZED).
 | 
						|
 *
 | 
						|
 * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
 | 
						|
 * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
 | 
						|
 * Refer to the OpenZFS git commit log for authoritative copyright attribution.
 | 
						|
 *
 | 
						|
 * The contents of this file are subject to the terms of the
 | 
						|
 * Common Development and Distribution License Version 1.0 (CDDL-1.0).
 | 
						|
 * You can obtain a copy of the license from the top-level file
 | 
						|
 * "OPENSOLARIS.LICENSE" or at <http://opensource.org/licenses/CDDL-1.0>.
 | 
						|
 * You may not use this file except in compliance with the license.
 | 
						|
 */
 | 
						|
 | 
						|
#include <assert.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <stddef.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <sys/avl.h>
 | 
						|
#include <sys/sysmacros.h>
 | 
						|
#include "zed_strings.h"
 | 
						|
 | 
						|
struct zed_strings {
 | 
						|
	avl_tree_t tree;
 | 
						|
	avl_node_t *iteratorp;
 | 
						|
};
 | 
						|
 | 
						|
struct zed_strings_node {
 | 
						|
	avl_node_t node;
 | 
						|
	char *key;
 | 
						|
	char *val;
 | 
						|
};
 | 
						|
 | 
						|
typedef struct zed_strings_node zed_strings_node_t;
 | 
						|
 | 
						|
/*
 | 
						|
 * Compare zed_strings_node_t nodes [x1] and [x2].
 | 
						|
 * As required for the AVL tree, return -1 for <, 0 for ==, and +1 for >.
 | 
						|
 */
 | 
						|
static int
 | 
						|
_zed_strings_node_compare(const void *x1, const void *x2)
 | 
						|
{
 | 
						|
	const char *s1;
 | 
						|
	const char *s2;
 | 
						|
	int rv;
 | 
						|
 | 
						|
	assert(x1 != NULL);
 | 
						|
	assert(x2 != NULL);
 | 
						|
 | 
						|
	s1 = ((const zed_strings_node_t *) x1)->key;
 | 
						|
	assert(s1 != NULL);
 | 
						|
	s2 = ((const zed_strings_node_t *) x2)->key;
 | 
						|
	assert(s2 != NULL);
 | 
						|
	rv = strcmp(s1, s2);
 | 
						|
 | 
						|
	if (rv < 0)
 | 
						|
		return (-1);
 | 
						|
 | 
						|
	if (rv > 0)
 | 
						|
		return (1);
 | 
						|
 | 
						|
	return (0);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return a new string container, or NULL on error.
 | 
						|
 */
 | 
						|
zed_strings_t *
 | 
						|
zed_strings_create(void)
 | 
						|
{
 | 
						|
	zed_strings_t *zsp;
 | 
						|
 | 
						|
	zsp = calloc(1, sizeof (*zsp));
 | 
						|
	if (!zsp)
 | 
						|
		return (NULL);
 | 
						|
 | 
						|
	avl_create(&zsp->tree, _zed_strings_node_compare,
 | 
						|
	    sizeof (zed_strings_node_t), offsetof(zed_strings_node_t, node));
 | 
						|
 | 
						|
	zsp->iteratorp = NULL;
 | 
						|
	return (zsp);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Destroy the string node [np].
 | 
						|
 */
 | 
						|
static void
 | 
						|
_zed_strings_node_destroy(zed_strings_node_t *np)
 | 
						|
{
 | 
						|
	if (!np)
 | 
						|
		return;
 | 
						|
 | 
						|
	if (np->key) {
 | 
						|
		if (np->key != np->val)
 | 
						|
			free(np->key);
 | 
						|
		np->key = NULL;
 | 
						|
	}
 | 
						|
	if (np->val) {
 | 
						|
		free(np->val);
 | 
						|
		np->val = NULL;
 | 
						|
	}
 | 
						|
	free(np);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return a new string node for storing the string [val], or NULL on error.
 | 
						|
 * If [key] is specified, it will be used to index the node; otherwise,
 | 
						|
 * the string [val] will be used.
 | 
						|
 */
 | 
						|
static zed_strings_node_t *
 | 
						|
_zed_strings_node_create(const char *key, const char *val)
 | 
						|
{
 | 
						|
	zed_strings_node_t *np;
 | 
						|
 | 
						|
	assert(val != NULL);
 | 
						|
 | 
						|
	np = calloc(1, sizeof (*np));
 | 
						|
	if (!np)
 | 
						|
		return (NULL);
 | 
						|
 | 
						|
	np->val = strdup(val);
 | 
						|
	if (!np->val)
 | 
						|
		goto nomem;
 | 
						|
 | 
						|
	if (key) {
 | 
						|
		np->key = strdup(key);
 | 
						|
		if (!np->key)
 | 
						|
			goto nomem;
 | 
						|
	} else {
 | 
						|
		np->key = np->val;
 | 
						|
	}
 | 
						|
	return (np);
 | 
						|
 | 
						|
nomem:
 | 
						|
	_zed_strings_node_destroy(np);
 | 
						|
	return (NULL);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Destroy the string container [zsp] and all nodes within.
 | 
						|
 */
 | 
						|
void
 | 
						|
zed_strings_destroy(zed_strings_t *zsp)
 | 
						|
{
 | 
						|
	void *cookie;
 | 
						|
	zed_strings_node_t *np;
 | 
						|
 | 
						|
	if (!zsp)
 | 
						|
		return;
 | 
						|
 | 
						|
	cookie = NULL;
 | 
						|
	while ((np = avl_destroy_nodes(&zsp->tree, &cookie)))
 | 
						|
		_zed_strings_node_destroy(np);
 | 
						|
 | 
						|
	avl_destroy(&zsp->tree);
 | 
						|
	free(zsp);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Add a copy of the string [s] indexed by [key] to the container [zsp].
 | 
						|
 * If [key] already exists within the container [zsp], it will be replaced
 | 
						|
 * with the new string [s].
 | 
						|
 * If [key] is NULL, the string [s] will be used as the key.
 | 
						|
 * Return 0 on success, or -1 on error.
 | 
						|
 */
 | 
						|
int
 | 
						|
zed_strings_add(zed_strings_t *zsp, const char *key, const char *s)
 | 
						|
{
 | 
						|
	zed_strings_node_t *newp, *oldp;
 | 
						|
 | 
						|
	if (!zsp || !s) {
 | 
						|
		errno = EINVAL;
 | 
						|
		return (-1);
 | 
						|
	}
 | 
						|
	if (key == s)
 | 
						|
		key = NULL;
 | 
						|
 | 
						|
	newp = _zed_strings_node_create(key, s);
 | 
						|
	if (!newp)
 | 
						|
		return (-1);
 | 
						|
 | 
						|
	oldp = avl_find(&zsp->tree, newp, NULL);
 | 
						|
	if (oldp) {
 | 
						|
		avl_remove(&zsp->tree, oldp);
 | 
						|
		_zed_strings_node_destroy(oldp);
 | 
						|
	}
 | 
						|
	avl_add(&zsp->tree, newp);
 | 
						|
	return (0);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return the first string in container [zsp].
 | 
						|
 * Return NULL if there are no strings, or on error.
 | 
						|
 * This can be called multiple times to re-traverse [zsp].
 | 
						|
 * XXX: Not thread-safe.
 | 
						|
 */
 | 
						|
const char *
 | 
						|
zed_strings_first(zed_strings_t *zsp)
 | 
						|
{
 | 
						|
	if (!zsp) {
 | 
						|
		errno = EINVAL;
 | 
						|
		return (NULL);
 | 
						|
	}
 | 
						|
	zsp->iteratorp = avl_first(&zsp->tree);
 | 
						|
	if (!zsp->iteratorp)
 | 
						|
		return (NULL);
 | 
						|
 | 
						|
	return (((zed_strings_node_t *)zsp->iteratorp)->val);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return the next string in container [zsp].
 | 
						|
 * Return NULL after the last string, or on error.
 | 
						|
 * This must be called after zed_strings_first().
 | 
						|
 * XXX: Not thread-safe.
 | 
						|
 */
 | 
						|
const char *
 | 
						|
zed_strings_next(zed_strings_t *zsp)
 | 
						|
{
 | 
						|
	if (!zsp) {
 | 
						|
		errno = EINVAL;
 | 
						|
		return (NULL);
 | 
						|
	}
 | 
						|
	if (!zsp->iteratorp)
 | 
						|
		return (NULL);
 | 
						|
 | 
						|
	zsp->iteratorp = AVL_NEXT(&zsp->tree, zsp->iteratorp);
 | 
						|
	if (!zsp->iteratorp)
 | 
						|
		return (NULL);
 | 
						|
 | 
						|
	return (((zed_strings_node_t *)zsp->iteratorp)->val);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return the number of strings in container [zsp], or -1 on error.
 | 
						|
 */
 | 
						|
int
 | 
						|
zed_strings_count(zed_strings_t *zsp)
 | 
						|
{
 | 
						|
	if (!zsp) {
 | 
						|
		errno = EINVAL;
 | 
						|
		return (-1);
 | 
						|
	}
 | 
						|
	return (avl_numnodes(&zsp->tree));
 | 
						|
}
 |