This commit adds functions to libzfs to check if one dataset is related

to another.

The `related_dataset()` function checks if the second provided dataset
is the same as or a child dataset of the first provided dataset. The
function returns a `boolean_t` value (`B_TRUE` if related).

The `zfs_related_dataset()` helper function takes a `zfs_handle_t` and
checks if the provided handle is related to the provided dataset. The
function returns a `boolean_t` value (`B_TRUE` if related).

libzfs_dataset.c:
- `related_dataset()`
- `zfs_related_dataset()`

libzfs.h:
- `zfs_related_dataset()`

Signed-off-by: QORTEC <lowell.bv@gmail.com>
This commit is contained in:
QORTEC 2023-10-10 17:07:16 -04:00
parent 4d1b70175c
commit f476a37b37
2 changed files with 30 additions and 0 deletions

View File

@ -887,6 +887,7 @@ _LIBZFS_H int zfs_name_valid(const char *, zfs_type_t);
_LIBZFS_H zfs_handle_t *zfs_path_to_zhandle(libzfs_handle_t *, const char *,
zfs_type_t);
_LIBZFS_H int zfs_parent_name(zfs_handle_t *, char *, size_t);
_LIBZFS_H boolean_t zfs_dataset_related(zfs_handle_t *, const char *);
_LIBZFS_H boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *,
zfs_type_t);
_LIBZFS_H int zfs_spa_version(zfs_handle_t *, int *);

View File

@ -3446,6 +3446,35 @@ is_descendant(const char *ds1, const char *ds2)
return (ds2[d1len] == '/' && (strncmp(ds1, ds2, d1len) == 0));
}
/*
* Is one dataset is related to another, including self-relation?
*
* Needs to handle these cases:
* Dataset 1 "a/foo" "a/foo" "a/foo" "a/foo"
* Dataset 2 "a/foo" "a/fo" "a/foobar" "a/foo/bar"
* Related? Yes. No. No. Yes.
*/
static boolean_t
dataset_related(const char *ds1, const char *ds2)
{
/* ds1 and ds2 are identical */
if (strcmp(ds1, ds2) == 0)
return (B_TRUE);
/* ds2 is a descendant of ds1 */
if (is_descendant(ds1, ds2))
return (B_TRUE);
/* dataset are not related. */
return (B_FALSE);
}
boolean_t
zfs_dataset_related(zfs_handle_t *zhp, const char *parent)
{
return (dataset_related(parent, zfs_get_name(zhp)));
}
/*
* Given a complete name, return just the portion that refers to the parent.
* Will return -1 if there is no parent (path is just the name of the