4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
25 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
26 * Copyright (c) 2016 Martin Matuska. All rights reserved.
30 * This file contains the functions used to support the ZFS integration
31 * with zones. This includes validation (e.g. zonecfg dataset), cloning,
32 * file system creation and destruction.
42 #include <sys/statvfs.h>
44 #include <libzonecfg.h>
45 #include <sys/mnttab.h>
47 #include <sys/mntent.h>
54 libzfs_handle_t
*g_zfs
;
56 typedef struct zfs_mount_data
{
58 zfs_handle_t
*match_handle
;
61 typedef struct zfs_snapshot_data
{
62 char *match_name
; /* zonename@SUNWzone */
63 int len
; /* strlen of match_name */
64 int max
; /* highest digit appended to snap name */
65 int num
; /* number of snapshots to rename */
66 int cntr
; /* counter for renaming snapshots */
67 } zfs_snapshot_data_t
;
69 typedef struct clone_data
{
70 zfs_handle_t
*clone_zhp
; /* clone dataset to promote */
71 time_t origin_creation
; /* snapshot creation time of clone */
72 const char *snapshot
; /* snapshot of dataset being demoted */
76 * A ZFS file system iterator call-back function which returns the
77 * zfs_handle_t for a ZFS file system on the specified mount point.
80 match_mountpoint(zfs_handle_t
*zhp
, void *data
)
83 zfs_mount_data_t
*cbp
;
84 char mp
[ZFS_MAXPROPLEN
];
86 if (zfs_get_type(zhp
) != ZFS_TYPE_FILESYSTEM
) {
91 /* First check if the dataset is mounted. */
92 if (zfs_prop_get(zhp
, ZFS_PROP_MOUNTED
, mp
, sizeof (mp
), NULL
, NULL
,
93 0, B_FALSE
) != 0 || strcmp(mp
, "no") == 0) {
98 /* Now check mount point. */
99 if (zfs_prop_get(zhp
, ZFS_PROP_MOUNTPOINT
, mp
, sizeof (mp
), NULL
, NULL
,
105 cbp
= (zfs_mount_data_t
*)data
;
107 if (strcmp(mp
, "legacy") == 0) {
108 /* If legacy, must look in mnttab for mountpoint. */
113 nm
= zfs_get_name(zhp
);
114 if ((fp
= fopen(MNTTAB
, "r")) == NULL
) {
119 while (getmntent(fp
, &entry
) == 0) {
120 if (strcmp(nm
, entry
.mnt_special
) == 0) {
121 if (strcmp(entry
.mnt_mountp
, cbp
->match_name
)
124 cbp
->match_handle
= zhp
;
132 } else if (strcmp(mp
, cbp
->match_name
) == 0) {
133 cbp
->match_handle
= zhp
;
137 /* Iterate over any nested datasets. */
138 res
= zfs_iter_filesystems(zhp
, match_mountpoint
, data
);
144 * Get ZFS handle for the specified mount point.
146 static zfs_handle_t
*
147 mount2zhandle(char *mountpoint
)
151 cb
.match_name
= mountpoint
;
152 cb
.match_handle
= NULL
;
153 (void) zfs_iter_root(g_zfs
, match_mountpoint
, &cb
);
154 return (cb
.match_handle
);
158 * Check if there is already a file system (zfs or any other type) mounted on
162 is_mountpnt(char *path
)
167 if ((fp
= fopen(MNTTAB
, "r")) == NULL
)
170 while (getmntent(fp
, &entry
) == 0) {
171 if (strcmp(path
, entry
.mnt_mountp
) == 0) {
182 * Run the brand's pre-snapshot hook before we take a ZFS snapshot of the zone.
185 pre_snapshot(char *presnapbuf
)
189 /* No brand-specific handler */
190 if (presnapbuf
[0] == '\0')
194 status
= do_subproc(presnapbuf
);
195 if ((status
= subproc_status(gettext("brand-specific presnapshot"),
196 status
, B_FALSE
)) != ZONE_SUBPROC_OK
)
203 * Run the brand's post-snapshot hook after we take a ZFS snapshot of the zone.
206 post_snapshot(char *postsnapbuf
)
210 /* No brand-specific handler */
211 if (postsnapbuf
[0] == '\0')
215 status
= do_subproc(postsnapbuf
);
216 if ((status
= subproc_status(gettext("brand-specific postsnapshot"),
217 status
, B_FALSE
)) != ZONE_SUBPROC_OK
)
224 * This is a ZFS snapshot iterator call-back function which returns the
225 * highest number of SUNWzone snapshots that have been taken.
228 get_snap_max(zfs_handle_t
*zhp
, void *data
)
231 zfs_snapshot_data_t
*cbp
;
233 if (zfs_get_type(zhp
) != ZFS_TYPE_SNAPSHOT
) {
238 cbp
= (zfs_snapshot_data_t
*)data
;
240 if (strncmp(zfs_get_name(zhp
), cbp
->match_name
, cbp
->len
) == 0) {
245 nump
= (char *)(zfs_get_name(zhp
) + cbp
->len
);
251 res
= zfs_iter_snapshots(zhp
, B_FALSE
, get_snap_max
, data
);
257 * Take a ZFS snapshot to be used for cloning the zone.
260 take_snapshot(zfs_handle_t
*zhp
, char *snapshot_name
, int snap_size
,
261 char *presnapbuf
, char *postsnapbuf
)
264 char template[ZFS_MAX_DATASET_NAME_LEN
];
265 zfs_snapshot_data_t cb
;
268 * First we need to figure out the next available name for the
269 * zone snapshot. Look through the list of zones snapshots for
270 * this file system to determine the maximum snapshot name.
272 if (snprintf(template, sizeof (template), "%s@SUNWzone",
273 zfs_get_name(zhp
)) >= sizeof (template))
276 cb
.match_name
= template;
277 cb
.len
= strlen(template);
280 if (zfs_iter_snapshots(zhp
, B_FALSE
, get_snap_max
, &cb
) != 0)
285 if (snprintf(snapshot_name
, snap_size
, "%s@SUNWzone%d",
286 zfs_get_name(zhp
), cb
.max
) >= snap_size
)
289 if (pre_snapshot(presnapbuf
) != Z_OK
)
291 res
= zfs_snapshot(g_zfs
, snapshot_name
, B_FALSE
, NULL
);
292 if (post_snapshot(postsnapbuf
) != Z_OK
)
301 * We are using an explicit snapshot from some earlier point in time so
302 * we need to validate it. Run the brand specific hook.
305 validate_snapshot(char *snapshot_name
, char *snap_path
, char *validsnapbuf
)
308 char cmdbuf
[MAXPATHLEN
];
310 /* No brand-specific handler */
311 if (validsnapbuf
[0] == '\0')
314 /* pass args - snapshot_name & snap_path */
315 if (snprintf(cmdbuf
, sizeof (cmdbuf
), "%s %s %s", validsnapbuf
,
316 snapshot_name
, snap_path
) >= sizeof (cmdbuf
)) {
317 zerror("Command line too long");
322 status
= do_subproc(cmdbuf
);
323 if ((status
= subproc_status(gettext("brand-specific validatesnapshot"),
324 status
, B_FALSE
)) != ZONE_SUBPROC_OK
)
331 * Remove the sw inventory file from inside this zonepath that we picked up out
338 zone_dochandle_t handle
;
340 if ((handle
= zonecfg_init_handle()) == NULL
) {
341 zperror(cmd_to_str(CMD_CLONE
), B_TRUE
);
345 if ((err
= zonecfg_get_handle(target_zone
, handle
)) != Z_OK
) {
347 zperror(cmd_to_str(CMD_CLONE
), B_TRUE
);
348 zonecfg_fini_handle(handle
);
352 zonecfg_rm_detached(handle
, B_FALSE
);
353 zonecfg_fini_handle(handle
);
359 * Make a ZFS clone on zonepath from snapshot_name.
362 clone_snap(char *snapshot_name
, char *zonepath
)
368 nvlist_t
*props
= NULL
;
370 if ((zhp
= zfs_open(g_zfs
, snapshot_name
, ZFS_TYPE_SNAPSHOT
)) == NULL
)
373 (void) printf(gettext("Cloning snapshot %s\n"), snapshot_name
);
376 * We turn off zfs SHARENFS and SHARESMB properties on the
377 * zoneroot dataset in order to prevent the GZ from sharing
378 * NGZ data by accident.
380 if ((nvlist_alloc(&props
, NV_UNIQUE_NAME
, 0) != 0) ||
381 (nvlist_add_string(props
, zfs_prop_to_name(ZFS_PROP_SHARENFS
),
383 (nvlist_add_string(props
, zfs_prop_to_name(ZFS_PROP_SHARESMB
),
386 (void) fprintf(stderr
, gettext("could not create ZFS clone "
387 "%s: out of memory\n"), zonepath
);
391 err
= zfs_clone(zhp
, zonepath
, props
);
399 /* create the mountpoint if necessary */
400 if ((clone
= zfs_open(g_zfs
, zonepath
, ZFS_TYPE_DATASET
)) == NULL
)
404 * The clone has been created so we need to print a diagnostic
405 * message if one of the following steps fails for some reason.
407 if (zfs_mount(clone
, NULL
, 0) != 0) {
408 (void) fprintf(stderr
, gettext("could not mount ZFS clone "
409 "%s\n"), zfs_get_name(clone
));
412 } else if (clean_out_clone() != Z_OK
) {
413 (void) fprintf(stderr
, gettext("could not remove the "
414 "software inventory from ZFS clone %s\n"),
415 zfs_get_name(clone
));
424 * This function takes a zonepath and attempts to determine what the ZFS
425 * file system name (not mountpoint) should be for that path. We do not
426 * assume that zonepath is an existing directory or ZFS fs since we use
427 * this function as part of the process of creating a new ZFS fs or clone.
429 * The way this works is that we look at the parent directory of the zonepath
430 * to see if it is a ZFS fs. If it is, we get the name of that ZFS fs and
431 * append the last component of the zonepath to generate the ZFS name for the
432 * zonepath. This matches the algorithm that ZFS uses for automatically
433 * mounting a new fs after it is created.
435 * Although a ZFS fs can be mounted anywhere, we don't worry about handling
436 * all of the complexity that a user could possibly configure with arbitrary
437 * mounts since there is no way to generate a ZFS name from a random path in
438 * the file system. We only try to handle the automatic mounts that ZFS does
439 * for each file system. ZFS restricts this so that a new fs must be created
440 * in an existing parent ZFS fs. It then automatically mounts the new fs
441 * directly under the mountpoint for the parent fs using the last component
442 * of the name as the mountpoint directory.
446 * space/eng/dev/test/zone1 /project1/eng/dev/test/zone1
448 * Return Z_OK if the path mapped to a ZFS file system name, otherwise return
452 path2name(char *zonepath
, char *zfs_name
, int len
)
455 char *bnm
, *dnm
, *dname
, *bname
;
460 * We need two tmp strings to handle paths directly in / (e.g. /foo)
461 * since dirname will overwrite the first char after "/" in this case.
463 if ((bnm
= strdup(zonepath
)) == NULL
)
466 if ((dnm
= strdup(zonepath
)) == NULL
) {
471 bname
= basename(bnm
);
472 dname
= dirname(dnm
);
475 * This is a quick test to save iterating over all of the zfs datasets
476 * on the system (which can be a lot). If the parent dir is not in a
477 * ZFS fs, then we're done.
479 if (stat(dname
, &stbuf
) != 0 || !S_ISDIR(stbuf
.st_mode
) ||
480 strcmp(stbuf
.st_fstype
, MNTTYPE_ZFS
) != 0) {
486 /* See if the parent directory is its own ZFS dataset. */
487 if ((zhp
= mount2zhandle(dname
)) == NULL
) {
489 * The parent is not a ZFS dataset so we can't automatically
490 * create a dataset on the given path.
497 res
= snprintf(zfs_name
, len
, "%s/%s", zfs_get_name(zhp
), bname
);
509 * A ZFS file system iterator call-back function used to determine if the
510 * file system has dependents (snapshots & clones).
514 has_dependent(zfs_handle_t
*zhp
, void *data
)
521 * Given a snapshot name, get the file system path where the snapshot lives.
522 * A snapshot name is of the form fs_name@snap_name. For example, snapshot
523 * pl/zones/z1@SUNWzone1 would have a path of
524 * /pl/zones/z1/.zfs/snapshot/SUNWzone1.
527 snap2path(char *snap_name
, char *path
, int len
)
531 char mp
[ZFS_MAXPROPLEN
];
533 if ((p
= strrchr(snap_name
, '@')) == NULL
)
536 /* Get the file system name from the snap_name. */
538 zhp
= zfs_open(g_zfs
, snap_name
, ZFS_TYPE_DATASET
);
543 /* Get the file system mount point. */
544 if (zfs_prop_get(zhp
, ZFS_PROP_MOUNTPOINT
, mp
, sizeof (mp
), NULL
, NULL
,
552 if (snprintf(path
, len
, "%s/.zfs/snapshot/%s", mp
, p
) >= len
)
559 * This callback function is used to iterate through a snapshot's dependencies
560 * to find a filesystem that is a direct clone of the snapshot being iterated.
563 get_direct_clone(zfs_handle_t
*zhp
, void *data
)
565 clone_data_t
*cd
= data
;
566 char origin
[ZFS_MAX_DATASET_NAME_LEN
];
567 char ds_path
[ZFS_MAX_DATASET_NAME_LEN
];
569 if (zfs_get_type(zhp
) != ZFS_TYPE_FILESYSTEM
) {
574 (void) strlcpy(ds_path
, zfs_get_name(zhp
), sizeof (ds_path
));
576 /* Make sure this is a direct clone of the snapshot we're iterating. */
577 if (zfs_prop_get(zhp
, ZFS_PROP_ORIGIN
, origin
, sizeof (origin
), NULL
,
578 NULL
, 0, B_FALSE
) != 0 || strcmp(origin
, cd
->snapshot
) != 0) {
583 if (cd
->clone_zhp
!= NULL
)
584 zfs_close(cd
->clone_zhp
);
591 * A ZFS file system iterator call-back function used to determine the clone
592 * to promote. This function finds the youngest (i.e. last one taken) snapshot
593 * that has a clone. If found, it returns a reference to that clone in the
597 find_clone(zfs_handle_t
*zhp
, void *data
)
599 clone_data_t
*cd
= data
;
600 time_t snap_creation
;
603 /* If snapshot has no clones, skip it */
604 if (zfs_prop_get_int(zhp
, ZFS_PROP_NUMCLONES
) == 0) {
609 cd
->snapshot
= zfs_get_name(zhp
);
611 /* Get the creation time of this snapshot */
612 snap_creation
= (time_t)zfs_prop_get_int(zhp
, ZFS_PROP_CREATION
);
615 * If this snapshot's creation time is greater than (i.e. younger than)
616 * the current youngest snapshot found, iterate this snapshot to
617 * get the right clone.
619 if (snap_creation
>= cd
->origin_creation
) {
621 * Iterate the dependents of this snapshot to find a clone
622 * that's a direct dependent.
624 if ((zret
= zfs_iter_dependents(zhp
, B_FALSE
, get_direct_clone
,
628 } else if (zret
== 1) {
630 * Found a clone, update the origin_creation time
631 * in the callback data.
633 cd
->origin_creation
= snap_creation
;
642 * A ZFS file system iterator call-back function used to remove standalone
647 rm_snap(zfs_handle_t
*zhp
, void *data
)
649 /* If snapshot has clones, something is wrong */
650 if (zfs_prop_get_int(zhp
, ZFS_PROP_NUMCLONES
) != 0) {
655 if (zfs_unmount(zhp
, NULL
, 0) == 0) {
656 (void) zfs_destroy(zhp
, B_FALSE
);
664 * A ZFS snapshot iterator call-back function which renames snapshots.
667 rename_snap(zfs_handle_t
*zhp
, void *data
)
670 zfs_snapshot_data_t
*cbp
;
671 char template[ZFS_MAX_DATASET_NAME_LEN
];
673 cbp
= (zfs_snapshot_data_t
*)data
;
676 * When renaming snapshots with the iterator, the iterator can see
677 * the same snapshot after we've renamed up in the namespace. To
678 * prevent this we check the count for the number of snapshots we have
679 * to rename and stop at that point.
681 if (cbp
->cntr
>= cbp
->num
) {
686 if (zfs_get_type(zhp
) != ZFS_TYPE_SNAPSHOT
) {
691 /* Only rename the snapshots we automatically generate when we clone. */
692 if (strncmp(zfs_get_name(zhp
), cbp
->match_name
, cbp
->len
) != 0) {
697 (void) snprintf(template, sizeof (template), "%s%d", cbp
->match_name
,
700 res
= (zfs_rename(zhp
, template, B_FALSE
, B_FALSE
) != 0);
702 (void) fprintf(stderr
, gettext("failed to rename snapshot %s "
703 "to %s: %s\n"), zfs_get_name(zhp
), template,
704 libzfs_error_description(g_zfs
));
713 * Rename the source dataset's snapshots that are automatically generated when
714 * we clone a zone so that there won't be a name collision when we promote the
715 * cloned dataset. Once the snapshots have been renamed, then promote the
718 * The snapshot rename process gets the highest number on the snapshot names
719 * (the format is zonename@SUNWzoneXX where XX are digits) on both the source
720 * and clone datasets, then renames the source dataset snapshots starting at
724 promote_clone(zfs_handle_t
*src_zhp
, zfs_handle_t
*cln_zhp
)
726 zfs_snapshot_data_t sd
;
727 char nm
[ZFS_MAX_DATASET_NAME_LEN
];
728 char template[ZFS_MAX_DATASET_NAME_LEN
];
730 (void) strlcpy(nm
, zfs_get_name(cln_zhp
), sizeof (nm
));
732 * Start by getting the clone's snapshot max which we use
733 * during the rename of the original dataset's snapshots.
735 (void) snprintf(template, sizeof (template), "%s@SUNWzone", nm
);
736 sd
.match_name
= template;
737 sd
.len
= strlen(template);
740 if (zfs_iter_snapshots(cln_zhp
, B_FALSE
, get_snap_max
, &sd
) != 0)
744 * Now make sure the source's snapshot max is at least as high as
745 * the clone's snapshot max.
747 (void) snprintf(template, sizeof (template), "%s@SUNWzone",
748 zfs_get_name(src_zhp
));
749 sd
.match_name
= template;
750 sd
.len
= strlen(template);
753 if (zfs_iter_snapshots(src_zhp
, B_FALSE
, get_snap_max
, &sd
) != 0)
757 * Now rename the source dataset's snapshots so there's no
758 * conflict when we promote the clone.
762 if (zfs_iter_snapshots(src_zhp
, B_FALSE
, rename_snap
, &sd
) != 0)
765 /* close and reopen the clone dataset to get the latest info */
767 if ((cln_zhp
= zfs_open(g_zfs
, nm
, ZFS_TYPE_FILESYSTEM
)) == NULL
)
770 if (zfs_promote(cln_zhp
) != 0) {
771 (void) fprintf(stderr
, gettext("failed to promote %s: %s\n"),
772 nm
, libzfs_error_description(g_zfs
));
781 * Promote the youngest clone. That clone will then become the origin of all
782 * of the other clones that were hanging off of the source dataset.
785 promote_all_clones(zfs_handle_t
*zhp
)
788 char nm
[ZFS_MAX_DATASET_NAME_LEN
];
791 cd
.origin_creation
= 0;
794 if (zfs_iter_snapshots(zhp
, B_FALSE
, find_clone
, &cd
) != 0) {
799 /* Nothing to promote. */
800 if (cd
.clone_zhp
== NULL
)
803 /* Found the youngest clone to promote. Promote it. */
804 if (promote_clone(zhp
, cd
.clone_zhp
) != 0) {
805 zfs_close(cd
.clone_zhp
);
810 /* close and reopen the main dataset to get the latest info */
811 (void) strlcpy(nm
, zfs_get_name(zhp
), sizeof (nm
));
813 if ((zhp
= zfs_open(g_zfs
, nm
, ZFS_TYPE_FILESYSTEM
)) == NULL
)
820 * Clone a pre-existing ZFS snapshot, either by making a direct ZFS clone, if
821 * possible, or by copying the data from the snapshot to the zonepath.
824 clone_snapshot_zfs(char *snap_name
, char *zonepath
, char *validatesnap
)
827 char clone_name
[MAXPATHLEN
];
828 char snap_path
[MAXPATHLEN
];
830 if (snap2path(snap_name
, snap_path
, sizeof (snap_path
)) != Z_OK
) {
831 (void) fprintf(stderr
, gettext("unable to find path for %s.\n"),
836 if (validate_snapshot(snap_name
, snap_path
, validatesnap
) != Z_OK
)
840 * The zonepath cannot be ZFS cloned, try to copy the data from
841 * within the snapshot to the zonepath.
843 if (path2name(zonepath
, clone_name
, sizeof (clone_name
)) != Z_OK
) {
844 if ((err
= clone_copy(snap_path
, zonepath
)) == Z_OK
)
845 if (clean_out_clone() != Z_OK
)
846 (void) fprintf(stderr
,
847 gettext("could not remove the "
848 "software inventory from %s\n"), zonepath
);
853 if ((err
= clone_snap(snap_name
, clone_name
)) != Z_OK
) {
854 if (err
!= Z_NO_ENTRY
) {
856 * Cloning the snapshot failed. Fall back to trying
857 * to install the zone by copying from the snapshot.
859 if ((err
= clone_copy(snap_path
, zonepath
)) == Z_OK
)
860 if (clean_out_clone() != Z_OK
)
861 (void) fprintf(stderr
,
862 gettext("could not remove the "
863 "software inventory from %s\n"),
867 * The snapshot is unusable for some reason so restore
868 * the zone state to configured since we were unable to
869 * actually do anything about getting the zone
874 if ((tmp
= zone_set_state(target_zone
,
875 ZONE_STATE_CONFIGURED
)) != Z_OK
) {
877 zperror2(target_zone
,
878 gettext("could not set state"));
887 * Attempt to clone a source_zone to a target zonepath by using a ZFS clone.
890 clone_zfs(char *source_zonepath
, char *zonepath
, char *presnapbuf
,
894 char clone_name
[MAXPATHLEN
];
895 char snap_name
[MAXPATHLEN
];
898 * Try to get a zfs handle for the source_zonepath. If this fails
899 * the source_zonepath is not ZFS so return an error.
901 if ((zhp
= mount2zhandle(source_zonepath
)) == NULL
)
905 * Check if there is a file system already mounted on zonepath. If so,
906 * we can't clone to the path so we should fall back to copying.
908 if (is_mountpnt(zonepath
)) {
910 (void) fprintf(stderr
,
911 gettext("A file system is already mounted on %s,\n"
912 "preventing use of a ZFS clone.\n"), zonepath
);
917 * Instead of using path2name to get the clone name from the zonepath,
918 * we could generate a name from the source zone ZFS name. However,
919 * this would mean we would create the clone under the ZFS fs of the
920 * source instead of what the zonepath says. For example,
922 * source_zonepath zonepath
923 * /pl/zones/dev/z1 /pl/zones/deploy/z2
925 * We don't want the clone to be under "dev", we want it under
926 * "deploy", so that we can leverage the normal attribute inheritance
927 * that ZFS provides in the fs hierarchy.
929 if (path2name(zonepath
, clone_name
, sizeof (clone_name
)) != Z_OK
) {
934 if (take_snapshot(zhp
, snap_name
, sizeof (snap_name
), presnapbuf
,
935 postsnapbuf
) != Z_OK
) {
941 if (clone_snap(snap_name
, clone_name
) != Z_OK
) {
942 /* Clean up the snapshot we just took. */
943 if ((zhp
= zfs_open(g_zfs
, snap_name
, ZFS_TYPE_SNAPSHOT
))
945 if (zfs_unmount(zhp
, NULL
, 0) == 0)
946 (void) zfs_destroy(zhp
, B_FALSE
);
953 (void) printf(gettext("Instead of copying, a ZFS clone has been "
954 "created for this zone.\n"));
960 * Attempt to create a ZFS file system for the specified zonepath.
961 * We either will successfully create a ZFS file system and get it mounted
962 * on the zonepath or we don't. The caller doesn't care since a regular
963 * directory is used for the zonepath if no ZFS file system is mounted there.
966 create_zfs_zonepath(char *zonepath
)
969 char zfs_name
[MAXPATHLEN
];
970 nvlist_t
*props
= NULL
;
972 if (path2name(zonepath
, zfs_name
, sizeof (zfs_name
)) != Z_OK
)
975 /* Check if the dataset already exists. */
976 if ((zhp
= zfs_open(g_zfs
, zfs_name
, ZFS_TYPE_DATASET
)) != NULL
) {
982 * We turn off zfs SHARENFS and SHARESMB properties on the
983 * zoneroot dataset in order to prevent the GZ from sharing
984 * NGZ data by accident.
986 if ((nvlist_alloc(&props
, NV_UNIQUE_NAME
, 0) != 0) ||
987 (nvlist_add_string(props
, zfs_prop_to_name(ZFS_PROP_SHARENFS
),
989 (nvlist_add_string(props
, zfs_prop_to_name(ZFS_PROP_SHARESMB
),
992 (void) fprintf(stderr
, gettext("cannot create ZFS dataset %s: "
993 "out of memory\n"), zfs_name
);
996 if (zfs_create(g_zfs
, zfs_name
, ZFS_TYPE_FILESYSTEM
, props
) != 0 ||
997 (zhp
= zfs_open(g_zfs
, zfs_name
, ZFS_TYPE_DATASET
)) == NULL
) {
998 (void) fprintf(stderr
, gettext("cannot create ZFS dataset %s: "
999 "%s\n"), zfs_name
, libzfs_error_description(g_zfs
));
1006 if (zfs_mount(zhp
, NULL
, 0) != 0) {
1007 (void) fprintf(stderr
, gettext("cannot mount ZFS dataset %s: "
1008 "%s\n"), zfs_name
, libzfs_error_description(g_zfs
));
1009 (void) zfs_destroy(zhp
, B_FALSE
);
1011 if (chmod(zonepath
, S_IRWXU
) != 0) {
1012 (void) fprintf(stderr
, gettext("file system %s "
1013 "successfully created, but chmod %o failed: %s\n"),
1014 zfs_name
, S_IRWXU
, strerror(errno
));
1015 (void) destroy_zfs(zonepath
);
1017 (void) printf(gettext("A ZFS file system has been "
1018 "created for this zone.\n"));
1026 * If the zonepath is a ZFS file system, attempt to destroy it. We return Z_OK
1027 * if we were able to zfs_destroy the zonepath, otherwise we return Z_ERR
1028 * which means the caller should clean up the zonepath in the traditional
1032 destroy_zfs(char *zonepath
)
1035 boolean_t is_clone
= B_FALSE
;
1036 char origin
[ZFS_MAXPROPLEN
];
1038 if ((zhp
= mount2zhandle(zonepath
)) == NULL
)
1041 if (promote_all_clones(zhp
) != 0)
1044 /* Now cleanup any snapshots remaining. */
1045 if (zfs_iter_snapshots(zhp
, B_FALSE
, rm_snap
, NULL
) != 0) {
1051 * We can't destroy the file system if it has still has dependents.
1052 * There shouldn't be any at this point, but we'll double check.
1054 if (zfs_iter_dependents(zhp
, B_TRUE
, has_dependent
, NULL
) != 0) {
1055 (void) fprintf(stderr
, gettext("zfs destroy %s failed: the "
1056 "dataset still has dependents\n"), zfs_get_name(zhp
));
1062 * This might be a clone. Try to get the snapshot so we can attempt
1063 * to destroy that as well.
1065 if (zfs_prop_get(zhp
, ZFS_PROP_ORIGIN
, origin
, sizeof (origin
), NULL
,
1066 NULL
, 0, B_FALSE
) == 0)
1069 if (zfs_unmount(zhp
, NULL
, 0) != 0) {
1070 (void) fprintf(stderr
, gettext("zfs unmount %s failed: %s\n"),
1071 zfs_get_name(zhp
), libzfs_error_description(g_zfs
));
1076 if (zfs_destroy(zhp
, B_FALSE
) != 0) {
1078 * If the destroy fails for some reason, try to remount
1079 * the file system so that we can use "rm -rf" to clean up
1082 (void) fprintf(stderr
, gettext("zfs destroy %s failed: %s\n"),
1083 zfs_get_name(zhp
), libzfs_error_description(g_zfs
));
1084 (void) zfs_mount(zhp
, NULL
, 0);
1090 * If the zone has ever been moved then the mountpoint dir will not be
1091 * cleaned up by the zfs_destroy(). To handle this case try to clean
1092 * it up now but don't worry if it fails, that will be normal.
1094 (void) rmdir(zonepath
);
1096 (void) printf(gettext("The ZFS file system for this zone has been "
1103 * Try to clean up the snapshot that the clone was taken from.
1105 if ((ohp
= zfs_open(g_zfs
, origin
,
1106 ZFS_TYPE_SNAPSHOT
)) != NULL
) {
1107 if (zfs_iter_dependents(ohp
, B_TRUE
, has_dependent
,
1108 NULL
) == 0 && zfs_unmount(ohp
, NULL
, 0) == 0)
1109 (void) zfs_destroy(ohp
, B_FALSE
);
1119 * Return true if the path is its own zfs file system. We determine this
1120 * by stat-ing the path to see if it is zfs and stat-ing the parent to see
1121 * if it is a different fs.
1124 is_zonepath_zfs(char *zonepath
)
1129 struct statvfs64 buf1
, buf2
;
1131 if (statvfs(zonepath
, &buf1
) != 0)
1134 if (strcmp(buf1
.f_basetype
, "zfs") != 0)
1137 if ((path
= strdup(zonepath
)) == NULL
)
1140 parent
= dirname(path
);
1141 res
= statvfs(parent
, &buf2
);
1147 if (buf1
.f_fsid
== buf2
.f_fsid
)
1154 * Implement the fast move of a ZFS file system by simply updating the
1155 * mountpoint. Since it is file system already, we don't have the
1156 * issue of cross-file system copying.
1159 move_zfs(char *zonepath
, char *new_zonepath
)
1164 if ((zhp
= mount2zhandle(zonepath
)) == NULL
)
1167 if (zfs_prop_set(zhp
, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT
),
1168 new_zonepath
) == 0) {
1170 * Clean up the old mount point. We ignore any failure since
1171 * the zone is already successfully mounted on the new path.
1173 (void) rmdir(zonepath
);
1183 * Validate that the given dataset exists on the system, and that neither it nor
1184 * its children are zvols.
1186 * Note that we don't do anything with the 'zoned' property here. All
1187 * management is done in zoneadmd when the zone is actually rebooted. This
1188 * allows us to automatically set the zoned property even when a zone is
1189 * rebooted by the administrator.
1192 verify_datasets(zone_dochandle_t handle
)
1194 int return_code
= Z_OK
;
1195 struct zone_dstab dstab
;
1197 char propbuf
[ZFS_MAXPROPLEN
];
1198 char source
[ZFS_MAX_DATASET_NAME_LEN
];
1199 zprop_source_t srctype
;
1201 if (zonecfg_setdsent(handle
) != Z_OK
) {
1204 * zfs and dataset are literals that should not be translated.
1206 (void) fprintf(stderr
, gettext("could not verify zfs datasets: "
1207 "unable to enumerate datasets\n"));
1211 while (zonecfg_getdsent(handle
, &dstab
) == Z_OK
) {
1213 if ((zhp
= zfs_open(g_zfs
, dstab
.zone_dataset_name
,
1214 ZFS_TYPE_FILESYSTEM
| ZFS_TYPE_VOLUME
)) == NULL
) {
1215 (void) fprintf(stderr
, gettext("could not verify zfs "
1216 "dataset %s: %s\n"), dstab
.zone_dataset_name
,
1217 libzfs_error_description(g_zfs
));
1218 return_code
= Z_ERR
;
1222 if (zfs_prop_get(zhp
, ZFS_PROP_MOUNTPOINT
, propbuf
,
1223 sizeof (propbuf
), &srctype
, source
,
1224 sizeof (source
), 0) == 0 &&
1225 (srctype
== ZPROP_SRC_INHERITED
)) {
1226 (void) fprintf(stderr
, gettext("could not verify zfs "
1227 "dataset %s: mountpoint cannot be inherited\n"),
1228 dstab
.zone_dataset_name
);
1229 return_code
= Z_ERR
;
1236 (void) zonecfg_enddsent(handle
);
1238 return (return_code
);
1242 * Verify that the ZFS dataset exists, and its mountpoint
1243 * property is set to "legacy".
1246 verify_fs_zfs(struct zone_fstab
*fstab
)
1249 char propbuf
[ZFS_MAXPROPLEN
];
1251 if ((zhp
= zfs_open(g_zfs
, fstab
->zone_fs_special
,
1252 ZFS_TYPE_DATASET
)) == NULL
) {
1253 (void) fprintf(stderr
, gettext("could not verify fs %s: "
1254 "could not access zfs dataset '%s'\n"),
1255 fstab
->zone_fs_dir
, fstab
->zone_fs_special
);
1259 if (zfs_get_type(zhp
) != ZFS_TYPE_FILESYSTEM
) {
1260 (void) fprintf(stderr
, gettext("cannot verify fs %s: "
1261 "'%s' is not a file system\n"),
1262 fstab
->zone_fs_dir
, fstab
->zone_fs_special
);
1267 if (zfs_prop_get(zhp
, ZFS_PROP_MOUNTPOINT
, propbuf
, sizeof (propbuf
),
1268 NULL
, NULL
, 0, 0) != 0 || strcmp(propbuf
, "legacy") != 0) {
1269 (void) fprintf(stderr
, gettext("could not verify fs %s: "
1270 "zfs '%s' mountpoint is not \"legacy\"\n"),
1271 fstab
->zone_fs_dir
, fstab
->zone_fs_special
);
1281 * Destroy the specified mnttab structure that was created by mnttab_dup().
1282 * NOTE: The structure's mnt_time field isn't freed.
1285 mnttab_destroy(struct mnttab
*tabp
)
1287 assert(tabp
!= NULL
);
1289 free(tabp
->mnt_mountp
);
1290 free(tabp
->mnt_special
);
1291 free(tabp
->mnt_fstype
);
1292 free(tabp
->mnt_mntopts
);
1297 * Duplicate the specified mnttab structure. The mnt_mountp and mnt_time
1298 * fields aren't duplicated. This function returns a pointer to the new mnttab
1299 * structure or NULL if an error occurred. If an error occurs, then this
1300 * function sets errno to reflect the error. mnttab structures created by
1301 * this function should be destroyed via mnttab_destroy().
1303 static struct mnttab
*
1304 mnttab_dup(const struct mnttab
*srcp
)
1306 struct mnttab
*retval
;
1308 assert(srcp
!= NULL
);
1310 retval
= (struct mnttab
*)calloc(1, sizeof (*retval
));
1311 if (retval
== NULL
) {
1315 if (srcp
->mnt_special
!= NULL
) {
1316 retval
->mnt_special
= strdup(srcp
->mnt_special
);
1317 if (retval
->mnt_special
== NULL
)
1320 if (srcp
->mnt_fstype
!= NULL
) {
1321 retval
->mnt_fstype
= strdup(srcp
->mnt_fstype
);
1322 if (retval
->mnt_fstype
== NULL
)
1325 retval
->mnt_mntopts
= (char *)malloc(MAX_MNTOPT_STR
* sizeof (char));
1326 if (retval
->mnt_mntopts
== NULL
)
1328 if (srcp
->mnt_mntopts
!= NULL
) {
1329 if (strlcpy(retval
->mnt_mntopts
, srcp
->mnt_mntopts
,
1330 MAX_MNTOPT_STR
* sizeof (char)) >= MAX_MNTOPT_STR
*
1332 mnttab_destroy(retval
);
1333 errno
= EOVERFLOW
; /* similar to mount(2) behavior */
1337 retval
->mnt_mntopts
[0] = '\0';
1342 mnttab_destroy(retval
);
1348 * Determine whether the specified ZFS dataset's mountpoint property is set
1349 * to "legacy". If the specified dataset does not have a legacy mountpoint,
1350 * then the string pointer to which the mountpoint argument points is assigned
1351 * a dynamically-allocated string containing the dataset's mountpoint
1352 * property. If the dataset's mountpoint property is "legacy" or a libzfs
1353 * error occurs, then the string pointer to which the mountpoint argument
1354 * points isn't modified.
1356 * This function returns B_TRUE if it doesn't encounter any fatal errors.
1357 * It returns B_FALSE if it encounters a fatal error and sets errno to the
1358 * appropriate error code.
1361 get_zfs_non_legacy_mountpoint(const char *dataset_name
, char **mountpoint
)
1364 char propbuf
[ZFS_MAXPROPLEN
];
1366 assert(dataset_name
!= NULL
);
1367 assert(mountpoint
!= NULL
);
1369 if ((zhp
= zfs_open(g_zfs
, dataset_name
, ZFS_TYPE_DATASET
)) == NULL
) {
1373 if (zfs_prop_get(zhp
, ZFS_PROP_MOUNTPOINT
, propbuf
, sizeof (propbuf
),
1374 NULL
, NULL
, 0, 0) != 0) {
1380 if (strcmp(propbuf
, "legacy") != 0) {
1381 if ((*mountpoint
= strdup(propbuf
)) == NULL
) {
1391 * This zonecfg_find_mounts() callback records information about mounts of
1392 * interest in a zonepath. It also tallies the number of zone
1393 * root overlay mounts and the number of unexpected mounts found.
1394 * This function outputs errors using zerror() if it finds unexpected
1395 * mounts. cookiep should point to an initialized zone_mounts_t structure.
1397 * This function returns zero on success and a nonzero value on failure.
1400 zone_mounts_cb(const struct mnttab
*mountp
, void *cookiep
)
1402 zone_mounts_t
*mounts
;
1403 const char *zone_mount_dir
;
1405 assert(mountp
!= NULL
);
1406 assert(cookiep
!= NULL
);
1408 mounts
= (zone_mounts_t
*)cookiep
;
1409 zone_mount_dir
= mountp
->mnt_mountp
+ mounts
->zonepath_len
;
1410 if (strcmp(zone_mount_dir
, "/root") == 0) {
1412 * Check for an overlay mount. If we already detected a /root
1413 * mount, then the current mount must be an overlay mount.
1415 if (mounts
->root_mnttab
!= NULL
) {
1416 mounts
->num_root_overlay_mounts
++;
1421 * Store the root mount's mnttab information in the
1422 * zone_mounts_t structure for future use.
1424 if ((mounts
->root_mnttab
= mnttab_dup(mountp
)) == NULL
) {
1425 zperror(cmd_to_str(CMD_MOVE
), B_FALSE
);
1430 * Determine if the filesystem is a ZFS filesystem with a
1431 * non-legacy mountpoint. If it is, then set the root
1432 * filesystem's mnttab's mnt_mountp field to a non-NULL
1433 * value, which will serve as a flag to indicate this special
1436 if (strcmp(mountp
->mnt_fstype
, MNTTYPE_ZFS
) == 0 &&
1437 get_zfs_non_legacy_mountpoint(mountp
->mnt_special
,
1438 &mounts
->root_mnttab
->mnt_mountp
) != B_TRUE
) {
1439 zperror(cmd_to_str(CMD_MOVE
), B_FALSE
);
1444 * An unexpected mount was found. Notify the user.
1446 if (mounts
->num_unexpected_mounts
== 0)
1447 zerror(gettext("These file systems are mounted on "
1448 "subdirectories of %s.\n"), mounts
->zonepath
);
1449 mounts
->num_unexpected_mounts
++;
1450 (void) zfm_print(mountp
, NULL
);
1456 * Initialize the specified zone_mounts_t structure for the given zonepath.
1457 * If this function succeeds, it returns zero and the specified zone_mounts_t
1458 * structure contains information about mounts in the specified zonepath.
1459 * The function returns a nonzero value if it fails. The zone_mounts_t
1460 * structure doesn't need be destroyed via zone_mounts_destroy() if this
1464 zone_mounts_init(zone_mounts_t
*mounts
, const char *zonepath
)
1466 assert(mounts
!= NULL
);
1467 assert(zonepath
!= NULL
);
1469 bzero(mounts
, sizeof (*mounts
));
1470 if ((mounts
->zonepath
= strdup(zonepath
)) == NULL
) {
1471 zerror(gettext("the process ran out of memory while checking "
1472 "for mounts in zonepath %s."), zonepath
);
1475 mounts
->zonepath_len
= strlen(zonepath
);
1476 if (zonecfg_find_mounts((char *)zonepath
, zone_mounts_cb
, mounts
) ==
1478 zerror(gettext("an error occurred while checking for mounts "
1479 "in zonepath %s."), zonepath
);
1480 zone_mounts_destroy(mounts
);
1487 * Destroy the memory used by the specified zone_mounts_t structure's fields.
1488 * This function doesn't free the memory occupied by the structure itself
1489 * (i.e., it doesn't free the parameter).
1492 zone_mounts_destroy(zone_mounts_t
*mounts
)
1494 assert(mounts
!= NULL
);
1496 free(mounts
->zonepath
);
1497 if (mounts
->root_mnttab
!= NULL
)
1498 mnttab_destroy(mounts
->root_mnttab
);
1502 * Mount a moving zone's root filesystem (if it had a root filesystem mount
1503 * prior to the move) using the specified zonepath. mounts should refer to
1504 * the zone_mounts_t structure describing the zone's mount information.
1506 * This function returns zero if the mount succeeds and a nonzero value
1510 zone_mount_rootfs(zone_mounts_t
*mounts
, const char *zonepath
)
1512 char zoneroot
[MAXPATHLEN
];
1513 struct mnttab
*mtab
;
1516 assert(mounts
!= NULL
);
1517 assert(zonepath
!= NULL
);
1520 * If there isn't a root filesystem, then don't do anything.
1522 mtab
= mounts
->root_mnttab
;
1527 * Determine the root filesystem's new mountpoint.
1529 if (snprintf(zoneroot
, sizeof (zoneroot
), "%s/root", zonepath
) >=
1530 sizeof (zoneroot
)) {
1531 zerror(gettext("Zonepath %s is too long.\n"), zonepath
);
1536 * If the root filesystem is a non-legacy ZFS filesystem (i.e., if it's
1537 * mnt_mountp field is non-NULL), then make the filesystem's new
1538 * mount point its mountpoint property and mount the filesystem.
1540 if (mtab
->mnt_mountp
!= NULL
) {
1543 if ((zhp
= zfs_open(g_zfs
, mtab
->mnt_special
,
1544 ZFS_TYPE_DATASET
)) == NULL
) {
1545 zerror(gettext("could not get ZFS handle for the zone's"
1546 " root filesystem"));
1549 if (zfs_prop_set(zhp
, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT
),
1551 zerror(gettext("could not modify zone's root "
1552 "filesystem's mountpoint property"));
1556 if (zfs_mount(zhp
, mtab
->mnt_mntopts
, 0) != 0) {
1557 zerror(gettext("unable to mount zone root %s: %s"),
1558 zoneroot
, libzfs_error_description(g_zfs
));
1559 if (zfs_prop_set(zhp
,
1560 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT
),
1561 mtab
->mnt_mountp
) != 0)
1562 zerror(gettext("unable to restore zone's root "
1563 "filesystem's mountpoint property"));
1572 * The root filesystem is either a legacy-mounted ZFS filesystem or
1573 * a non-ZFS filesystem. Use mount(2) to mount the root filesystem.
1575 if (mtab
->mnt_mntopts
!= NULL
)
1576 flags
= MS_OPTIONSTR
;
1579 if (mount(mtab
->mnt_special
, zoneroot
, flags
, mtab
->mnt_fstype
, NULL
, 0,
1580 mtab
->mnt_mntopts
, MAX_MNTOPT_STR
* sizeof (char)) != 0) {
1582 zerror(gettext("unable to mount zone root %s: %s"), zoneroot
,
1590 * Unmount a moving zone's root filesystem (if such a mount exists) using the
1591 * specified zonepath. mounts should refer to the zone_mounts_t structure
1592 * describing the zone's mount information. If force is B_TRUE, then if the
1593 * unmount fails, then the function will try to forcibly unmount the zone's root
1596 * This function returns zero if the unmount (forced or otherwise) succeeds;
1597 * otherwise, it returns a nonzero value.
1600 zone_unmount_rootfs(zone_mounts_t
*mounts
, const char *zonepath
,
1603 char zoneroot
[MAXPATHLEN
];
1604 struct mnttab
*mtab
;
1607 assert(mounts
!= NULL
);
1608 assert(zonepath
!= NULL
);
1611 * If there isn't a root filesystem, then don't do anything.
1613 mtab
= mounts
->root_mnttab
;
1618 * Determine the root filesystem's mountpoint.
1620 if (snprintf(zoneroot
, sizeof (zoneroot
), "%s/root", zonepath
) >=
1621 sizeof (zoneroot
)) {
1622 zerror(gettext("Zonepath %s is too long.\n"), zonepath
);
1627 * If the root filesystem is a non-legacy ZFS fileystem, then unmount
1628 * the filesystem via libzfs.
1630 if (mtab
->mnt_mountp
!= NULL
) {
1633 if ((zhp
= zfs_open(g_zfs
, mtab
->mnt_special
,
1634 ZFS_TYPE_DATASET
)) == NULL
) {
1635 zerror(gettext("could not get ZFS handle for the zone's"
1636 " root filesystem"));
1639 if (zfs_unmount(zhp
, zoneroot
, 0) != 0) {
1640 if (force
&& zfs_unmount(zhp
, zoneroot
, MS_FORCE
) ==
1645 zerror(gettext("unable to unmount zone root %s: %s"),
1646 zoneroot
, libzfs_error_description(g_zfs
));
1655 * Use umount(2) to unmount the root filesystem. If this fails, then
1656 * forcibly unmount it if the force flag is set.
1658 if (umount(zoneroot
) != 0) {
1659 if (force
&& umount2(zoneroot
, MS_FORCE
) == 0)
1662 zerror(gettext("unable to unmount zone root %s: %s"), zoneroot
,
1672 if ((g_zfs
= libzfs_init()) == NULL
) {
1673 (void) fprintf(stderr
, gettext("failed to initialize ZFS "