libzfs_iter.c revision 19b94df933188a15d4f0d6c568f0bab3f127892e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <stddef.h>
#include <libintl.h>
#include <libzfs.h>
#include "libzfs_impl.h"
int
{
return (0);
if (err != 0)
return (err);
}
}
return (0);
}
static int
{
int rc;
top:
if (rc == -1) {
switch (errno) {
case ENOMEM:
/* expand nvlist memory and try again */
return (-1);
}
goto top;
/*
* An errno value of ESRCH indicates normal completion.
* If ENOENT is returned, then the underlying dataset
* has been removed since we obtained the handle.
*/
case ESRCH:
case ENOENT:
rc = 1;
break;
default:
"cannot iterate filesystems"));
break;
}
}
return (rc);
}
/*
* Iterate over all child filesystems
*/
int
{
int ret;
return (0);
return (-1);
&zc)) == 0) {
/*
* Silently ignore errors, as the only plausible explanation is
* that the pool has since been removed.
*/
continue;
}
return (ret);
}
}
}
/*
* Iterate over all snapshots
*/
int
{
int ret;
return (0);
return (-1);
&zc)) == 0) {
continue;
}
return (ret);
}
}
}
/*
* Routines for dealing with the sorted snapshot functionality
*/
typedef struct zfs_node {
} zfs_node_t;
static int
{
if (node) {
/*
* If this snapshot was renamed while we were creating the
* AVL tree, it's possible that we already inserted it under
* its old name. Remove the old handle before adding the new
* one.
*/
}
return (0);
}
static int
{
/*
* Sort them according to creation time. We use the hidden
* CREATETXG property to get an absolute ordering of snapshots.
*/
return (-1);
return (+1);
else
return (0);
}
int
{
int ret = 0;
avl_destroy(&avl);
return (ret);
}
typedef struct {
char *ssa_first;
char *ssa_last;
void *ssa_arg;
static int
char *shortsnapname;
int err = 0;
if (ssa->ssa_seenlast)
return (0);
if (ssa->ssa_seenfirst) {
} else {
}
return (err);
}
/*
* spec is a string like "A,B%C,D"
*
* <snaps>, where <snaps> can be:
* <snap> (single snapshot)
* <snap>%<snap> (range of snapshots, inclusive)
* %<snap> (range of snapshots, starting with earliest)
* <snap>% (range of snapshots, ending with last)
* % (all snapshots)
* <snaps>[,...] (comma separated list of the above)
*
* If a snapshot can not be opened, continue trying to open the others, but
* return ENOENT at the end.
*/
int
{
char buf[ZFS_MAXNAMELEN];
char *comma_separated, *cp;
int err = 0;
int ret = 0;
snapspec_arg_t ssa = { 0 };
if (pct == comma_separated)
else
*pct = '\0';
/*
* If there is a lastname specified, make sure it
* exists.
*/
char snapname[ZFS_MAXNAMELEN];
continue;
}
}
snapspec_cb, &ssa);
if (ret == 0)
}
} else {
char snapname[ZFS_MAXNAMELEN];
snapname);
continue;
}
if (ret == 0)
}
}
return (ret);
}
/*
* Iterate over all children, snapshots and filesystems
*/
int
{
int ret;
return (ret);
}
typedef struct iter_stack_frame {
struct iter_stack_frame *next;
typedef struct iter_dependents_arg {
void *data;
static int
{
int err;
} else {
/*
* check if there is a cycle by seeing if this fs is already
* on the stack.
*/
if (ida->allowrecursion) {
return (0);
} else {
"recursive dependency at '%s'"),
zfs_get_name(zhp));
"cannot determine dependent "
"datasets"));
return (err);
}
}
}
if (err == 0)
}
return (err);
}
int
{
}