8264 want support for promoting datasets in libzfs_core

illumos/illumos-gate@a4b8c9aa65
a4b8c9aa65

https://www.illumos.org/issues/8264
  Oddly there is a lzc_clone function, but no lzc_promote function.

Reviewed by: Andriy Gapon <avg@FreeBSD.org>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Dan McDonald <danmcd@kebe.com>
Approved by: Dan McDonald <danmcd@kebe.com>
Author: Andrew Stormont <astormont@racktopsystems.com>
This commit is contained in:
Andriy Gapon 2017-06-14 16:23:15 +00:00
parent acb89578f1
commit 71672e5c5d
3 changed files with 33 additions and 14 deletions

View File

@ -30,6 +30,7 @@
* Copyright (c) 2014 Integros [integros.com] * Copyright (c) 2014 Integros [integros.com]
* Copyright 2016 Nexenta Systems, Inc. * Copyright 2016 Nexenta Systems, Inc.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com> * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
* Copyright 2017 RackTop Systems.
*/ */
#include <ctype.h> #include <ctype.h>
@ -3630,8 +3631,7 @@ int
zfs_promote(zfs_handle_t *zhp) zfs_promote(zfs_handle_t *zhp)
{ {
libzfs_handle_t *hdl = zhp->zfs_hdl; libzfs_handle_t *hdl = zhp->zfs_hdl;
zfs_cmd_t zc = { 0 }; char snapname[ZFS_MAX_DATASET_NAME_LEN];
char parent[MAXPATHLEN];
int ret; int ret;
char errbuf[1024]; char errbuf[1024];
@ -3644,31 +3644,25 @@ zfs_promote(zfs_handle_t *zhp)
return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
} }
(void) strlcpy(parent, zhp->zfs_dmustats.dds_origin, sizeof (parent)); if (zhp->zfs_dmustats.dds_origin[0] == '\0') {
if (parent[0] == '\0') {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"not a cloned filesystem")); "not a cloned filesystem"));
return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
} }
(void) strlcpy(zc.zc_value, zhp->zfs_dmustats.dds_origin, ret = lzc_promote(zhp->zfs_name, snapname, sizeof (snapname));
sizeof (zc.zc_value));
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
ret = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
if (ret != 0) { if (ret != 0) {
int save_errno = errno; switch (ret) {
switch (save_errno) {
case EEXIST: case EEXIST:
/* There is a conflicting snapshot name. */ /* There is a conflicting snapshot name. */
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"conflicting snapshot '%s' from parent '%s'"), "conflicting snapshot '%s' from parent '%s'"),
zc.zc_string, parent); snapname, zhp->zfs_dmustats.dds_origin);
return (zfs_error(hdl, EZFS_EXISTS, errbuf)); return (zfs_error(hdl, EZFS_EXISTS, errbuf));
default: default:
return (zfs_standard_error(hdl, save_errno, errbuf)); return (zfs_standard_error(hdl, ret, errbuf));
} }
} }
return (ret); return (ret);

View File

@ -23,6 +23,7 @@
* Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved.
* Copyright (c) 2014 Integros [integros.com] * Copyright (c) 2014 Integros [integros.com]
* Copyright 2017 RackTop Systems.
*/ */
/* /*
@ -203,6 +204,28 @@ lzc_clone(const char *fsname, const char *origin,
return (error); return (error);
} }
int
lzc_promote(const char *fsname, char *snapnamebuf, int snapnamelen)
{
/*
* The promote ioctl is still legacy, so we need to construct our
* own zfs_cmd_t rather than using lzc_ioctl().
*/
zfs_cmd_t zc = { 0 };
ASSERT3S(g_refcount, >, 0);
VERIFY3S(g_fd, !=, -1);
(void) strlcpy(zc.zc_name, fsname, sizeof (zc.zc_name));
if (ioctl(g_fd, ZFS_IOC_PROMOTE, &zc) != 0) {
int error = errno;
if (error == EEXIST && snapnamebuf != NULL)
(void) strlcpy(snapnamebuf, zc.zc_string, snapnamelen);
return (error);
}
return (0);
}
/* /*
* Creates snapshots. * Creates snapshots.
* *
@ -330,7 +353,7 @@ lzc_exists(const char *dataset)
{ {
/* /*
* The objset_stats ioctl is still legacy, so we need to construct our * The objset_stats ioctl is still legacy, so we need to construct our
* own zfs_cmd_t rather than using zfsc_ioctl(). * own zfs_cmd_t rather than using lzc_ioctl().
*/ */
zfs_cmd_t zc = { 0 }; zfs_cmd_t zc = { 0 };

View File

@ -22,6 +22,7 @@
/* /*
* Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com] * Copyright (c) 2014 Integros [integros.com]
* Copyright 2017 RackTop Systems.
*/ */
#ifndef _LIBZFS_CORE_H #ifndef _LIBZFS_CORE_H
@ -49,6 +50,7 @@ enum lzc_dataset_type {
int lzc_snapshot(nvlist_t *, nvlist_t *, nvlist_t **); int lzc_snapshot(nvlist_t *, nvlist_t *, nvlist_t **);
int lzc_create(const char *, enum lzc_dataset_type, nvlist_t *); int lzc_create(const char *, enum lzc_dataset_type, nvlist_t *);
int lzc_clone(const char *, const char *, nvlist_t *); int lzc_clone(const char *, const char *, nvlist_t *);
int lzc_promote(const char *, char *, int);
int lzc_destroy_snaps(nvlist_t *, boolean_t, nvlist_t **); int lzc_destroy_snaps(nvlist_t *, boolean_t, nvlist_t **);
int lzc_bookmark(nvlist_t *, nvlist_t **); int lzc_bookmark(nvlist_t *, nvlist_t **);
int lzc_get_bookmarks(const char *, nvlist_t *, nvlist_t **); int lzc_get_bookmarks(const char *, nvlist_t *, nvlist_t **);