diff options
author | jv227347 <Jordan.Vaughan@Sun.com> | 2009-12-07 16:44:49 -0800 |
---|---|---|
committer | jv227347 <Jordan.Vaughan@Sun.com> | 2009-12-07 16:44:49 -0800 |
commit | 0094b373ead542a342e4250eaf37854ccd3e50c0 (patch) | |
tree | c69e6bf413789e6956ec187f6b1e7efea1137548 /usr/src | |
parent | 0f79c548a94d01d7494ec7ffa3bc72cda00b4f7c (diff) | |
download | illumos-gate-0094b373ead542a342e4250eaf37854ccd3e50c0.tar.gz |
6880335 zoneadm move needs brand hook
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/zoneadm/zfs.c | 391 | ||||
-rw-r--r-- | usr/src/cmd/zoneadm/zoneadm.c | 95 | ||||
-rw-r--r-- | usr/src/cmd/zoneadm/zoneadm.h | 43 | ||||
-rw-r--r-- | usr/src/cmd/zoneadmd/vplat.c | 4 | ||||
-rw-r--r-- | usr/src/head/libzonecfg.h | 5 | ||||
-rw-r--r-- | usr/src/lib/brand/native/zone/sw_support.c | 4 | ||||
-rw-r--r-- | usr/src/lib/libzonecfg/common/libzonecfg.c | 8 |
7 files changed, 519 insertions, 31 deletions
diff --git a/usr/src/cmd/zoneadm/zfs.c b/usr/src/cmd/zoneadm/zfs.c index 1d52db5a66..694f44937e 100644 --- a/usr/src/cmd/zoneadm/zfs.c +++ b/usr/src/cmd/zoneadm/zfs.c @@ -44,6 +44,8 @@ #include <libzfs.h> #include <sys/mntent.h> #include <values.h> +#include <strings.h> +#include <assert.h> #include "zoneadm.h" @@ -1300,6 +1302,395 @@ verify_fs_zfs(struct zone_fstab *fstab) return (Z_OK); } +/* + * Destroy the specified mnttab structure that was created by mnttab_dup(). + * NOTE: The structure's mnt_time field isn't freed. + */ +static void +mnttab_destroy(struct mnttab *tabp) +{ + assert(tabp != NULL); + + free(tabp->mnt_mountp); + free(tabp->mnt_special); + free(tabp->mnt_fstype); + free(tabp->mnt_mntopts); + free(tabp); +} + +/* + * Duplicate the specified mnttab structure. The mnt_mountp and mnt_time + * fields aren't duplicated. This function returns a pointer to the new mnttab + * structure or NULL if an error occurred. If an error occurs, then this + * function sets errno to reflect the error. mnttab structures created by + * this function should be destroyed via mnttab_destroy(). + */ +static struct mnttab * +mnttab_dup(const struct mnttab *srcp) +{ + struct mnttab *retval; + + assert(srcp != NULL); + + retval = (struct mnttab *)calloc(1, sizeof (*retval)); + if (retval == NULL) { + errno = ENOMEM; + return (NULL); + } + if (srcp->mnt_special != NULL) { + retval->mnt_special = strdup(srcp->mnt_special); + if (retval->mnt_special == NULL) + goto err; + } + if (srcp->mnt_fstype != NULL) { + retval->mnt_fstype = strdup(srcp->mnt_fstype); + if (retval->mnt_fstype == NULL) + goto err; + } + retval->mnt_mntopts = (char *)malloc(MAX_MNTOPT_STR * sizeof (char)); + if (retval->mnt_mntopts == NULL) + goto err; + if (srcp->mnt_mntopts != NULL) { + if (strlcpy(retval->mnt_mntopts, srcp->mnt_mntopts, + MAX_MNTOPT_STR * sizeof (char)) >= MAX_MNTOPT_STR * + sizeof (char)) { + mnttab_destroy(retval); + errno = EOVERFLOW; /* similar to mount(2) behavior */ + return (NULL); + } + } else { + retval->mnt_mntopts[0] = '\0'; + } + return (retval); + +err: + mnttab_destroy(retval); + errno = ENOMEM; + return (NULL); +} + +/* + * Determine whether the specified ZFS dataset's mountpoint property is set + * to "legacy". If the specified dataset does not have a legacy mountpoint, + * then the string pointer to which the mountpoint argument points is assigned + * a dynamically-allocated string containing the dataset's mountpoint + * property. If the dataset's mountpoint property is "legacy" or a libzfs + * error occurs, then the string pointer to which the mountpoint argument + * points isn't modified. + * + * This function returns B_TRUE if it doesn't encounter any fatal errors. + * It returns B_FALSE if it encounters a fatal error and sets errno to the + * appropriate error code. + */ +static boolean_t +get_zfs_non_legacy_mountpoint(const char *dataset_name, char **mountpoint) +{ + zfs_handle_t *zhp; + char propbuf[ZFS_MAXPROPLEN]; + + assert(dataset_name != NULL); + assert(mountpoint != NULL); + + if ((zhp = zfs_open(g_zfs, dataset_name, ZFS_TYPE_DATASET)) == NULL) { + errno = EINVAL; + return (B_FALSE); + } + if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, propbuf, sizeof (propbuf), + NULL, NULL, 0, 0) != 0) { + zfs_close(zhp); + errno = EINVAL; + return (B_FALSE); + } + zfs_close(zhp); + if (strcmp(propbuf, "legacy") != 0) { + if ((*mountpoint = strdup(propbuf)) == NULL) { + errno = ENOMEM; + return (B_FALSE); + } + } + return (B_TRUE); +} + + +/* + * This zonecfg_find_mounts() callback records information about mounts of + * interest in a zonepath. It also tallies the number of zone + * root overlay mounts and the number of unexpected mounts found. + * This function outputs errors using zerror() if it finds unexpected + * mounts. cookiep should point to an initialized zone_mounts_t structure. + * + * This function returns zero on success and a nonzero value on failure. + */ +static int +zone_mounts_cb(const struct mnttab *mountp, void *cookiep) +{ + zone_mounts_t *mounts; + const char *zone_mount_dir; + + assert(mountp != NULL); + assert(cookiep != NULL); + + mounts = (zone_mounts_t *)cookiep; + zone_mount_dir = mountp->mnt_mountp + mounts->zonepath_len; + if (strcmp(zone_mount_dir, "/root") == 0) { + /* + * Check for an overlay mount. If we already detected a /root + * mount, then the current mount must be an overlay mount. + */ + if (mounts->root_mnttab != NULL) { + mounts->num_root_overlay_mounts++; + return (0); + } + + /* + * Store the root mount's mnttab information in the + * zone_mounts_t structure for future use. + */ + if ((mounts->root_mnttab = mnttab_dup(mountp)) == NULL) { + zperror(cmd_to_str(CMD_MOVE), B_FALSE); + return (-1); + } + + /* + * Determine if the filesystem is a ZFS filesystem with a + * non-legacy mountpoint. If it is, then set the root + * filesystem's mnttab's mnt_mountp field to a non-NULL + * value, which will serve as a flag to indicate this special + * condition. + */ + if (strcmp(mountp->mnt_fstype, MNTTYPE_ZFS) == 0 && + get_zfs_non_legacy_mountpoint(mountp->mnt_special, + &mounts->root_mnttab->mnt_mountp) != B_TRUE) { + zperror(cmd_to_str(CMD_MOVE), B_FALSE); + return (-1); + } + } else { + /* + * An unexpected mount was found. Notify the user. + */ + if (mounts->num_unexpected_mounts == 0) + zerror(gettext("These file systems are mounted on " + "subdirectories of %s.\n"), mounts->zonepath); + mounts->num_unexpected_mounts++; + (void) zfm_print(mountp, NULL); + } + return (0); +} + +/* + * Initialize the specified zone_mounts_t structure for the given zonepath. + * If this function succeeds, it returns zero and the specified zone_mounts_t + * structure contains information about mounts in the specified zonepath. + * The function returns a nonzero value if it fails. The zone_mounts_t + * structure doesn't need be destroyed via zone_mounts_destroy() if this + * function fails. + */ +int +zone_mounts_init(zone_mounts_t *mounts, const char *zonepath) +{ + assert(mounts != NULL); + assert(zonepath != NULL); + + bzero(mounts, sizeof (*mounts)); + if ((mounts->zonepath = strdup(zonepath)) == NULL) { + zerror(gettext("the process ran out of memory while checking " + "for mounts in zonepath %s."), zonepath); + return (-1); + } + mounts->zonepath_len = strlen(zonepath); + if (zonecfg_find_mounts((char *)zonepath, zone_mounts_cb, mounts) == + -1) { + zerror(gettext("an error occurred while checking for mounts " + "in zonepath %s."), zonepath); + zone_mounts_destroy(mounts); + return (-1); + } + return (0); +} + +/* + * Destroy the memory used by the specified zone_mounts_t structure's fields. + * This function doesn't free the memory occupied by the structure itself + * (i.e., it doesn't free the parameter). + */ +void +zone_mounts_destroy(zone_mounts_t *mounts) +{ + assert(mounts != NULL); + + free(mounts->zonepath); + if (mounts->root_mnttab != NULL) + mnttab_destroy(mounts->root_mnttab); +} + +/* + * Mount a moving zone's root filesystem (if it had a root filesystem mount + * prior to the move) using the specified zonepath. mounts should refer to + * the zone_mounts_t structure describing the zone's mount information. + * + * This function returns zero if the mount succeeds and a nonzero value + * if it doesn't. + */ +int +zone_mount_rootfs(zone_mounts_t *mounts, const char *zonepath) +{ + char zoneroot[MAXPATHLEN]; + struct mnttab *mtab; + int flags; + + assert(mounts != NULL); + assert(zonepath != NULL); + + /* + * If there isn't a root filesystem, then don't do anything. + */ + mtab = mounts->root_mnttab; + if (mtab == NULL) + return (0); + + /* + * Determine the root filesystem's new mountpoint. + */ + if (snprintf(zoneroot, sizeof (zoneroot), "%s/root", zonepath) >= + sizeof (zoneroot)) { + zerror(gettext("Zonepath %s is too long.\n"), zonepath); + return (-1); + } + + /* + * If the root filesystem is a non-legacy ZFS filesystem (i.e., if it's + * mnt_mountp field is non-NULL), then make the filesystem's new + * mount point its mountpoint property and mount the filesystem. + */ + if (mtab->mnt_mountp != NULL) { + zfs_handle_t *zhp; + + if ((zhp = zfs_open(g_zfs, mtab->mnt_special, + ZFS_TYPE_DATASET)) == NULL) { + zerror(gettext("could not get ZFS handle for the zone's" + " root filesystem")); + return (-1); + } + if (zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), + zoneroot) != 0) { + zerror(gettext("could not modify zone's root " + "filesystem's mountpoint property")); + zfs_close(zhp); + return (-1); + } + if (zfs_mount(zhp, mtab->mnt_mntopts, 0) != 0) { + zerror(gettext("unable to mount zone root %s: %s"), + zoneroot, libzfs_error_description(g_zfs)); + if (zfs_prop_set(zhp, + zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), + mtab->mnt_mountp) != 0) + zerror(gettext("unable to restore zone's root " + "filesystem's mountpoint property")); + zfs_close(zhp); + return (-1); + } + zfs_close(zhp); + return (0); + } + + /* + * The root filesystem is either a legacy-mounted ZFS filesystem or + * a non-ZFS filesystem. Use mount(2) to mount the root filesystem. + */ + if (mtab->mnt_mntopts != NULL) + flags = MS_OPTIONSTR; + else + flags = 0; + if (mount(mtab->mnt_special, zoneroot, flags, mtab->mnt_fstype, NULL, 0, + mtab->mnt_mntopts, MAX_MNTOPT_STR * sizeof (char)) != 0) { + flags = errno; + zerror(gettext("unable to mount zone root %s: %s"), zoneroot, + strerror(flags)); + return (-1); + } + return (0); +} + +/* + * Unmount a moving zone's root filesystem (if such a mount exists) using the + * specified zonepath. mounts should refer to the zone_mounts_t structure + * describing the zone's mount information. If force is B_TRUE, then if the + * unmount fails, then the function will try to forcibly unmount the zone's root + * filesystem. + * + * This function returns zero if the unmount (forced or otherwise) succeeds; + * otherwise, it returns a nonzero value. + */ +int +zone_unmount_rootfs(zone_mounts_t *mounts, const char *zonepath, + boolean_t force) +{ + char zoneroot[MAXPATHLEN]; + struct mnttab *mtab; + int err; + + assert(mounts != NULL); + assert(zonepath != NULL); + + /* + * If there isn't a root filesystem, then don't do anything. + */ + mtab = mounts->root_mnttab; + if (mtab == NULL) + return (0); + + /* + * Determine the root filesystem's mountpoint. + */ + if (snprintf(zoneroot, sizeof (zoneroot), "%s/root", zonepath) >= + sizeof (zoneroot)) { + zerror(gettext("Zonepath %s is too long.\n"), zonepath); + return (-1); + } + + /* + * If the root filesystem is a non-legacy ZFS fileystem, then unmount + * the filesystem via libzfs. + */ + if (mtab->mnt_mountp != NULL) { + zfs_handle_t *zhp; + + if ((zhp = zfs_open(g_zfs, mtab->mnt_special, + ZFS_TYPE_DATASET)) == NULL) { + zerror(gettext("could not get ZFS handle for the zone's" + " root filesystem")); + return (-1); + } + if (zfs_unmount(zhp, zoneroot, 0) != 0) { + if (force && zfs_unmount(zhp, zoneroot, MS_FORCE) == + 0) { + zfs_close(zhp); + return (0); + } + zerror(gettext("unable to unmount zone root %s: %s"), + zoneroot, libzfs_error_description(g_zfs)); + zfs_close(zhp); + return (-1); + } + zfs_close(zhp); + return (0); + } + + /* + * Use umount(2) to unmount the root filesystem. If this fails, then + * forcibly unmount it if the force flag is set. + */ + if (umount(zoneroot) != 0) { + if (force && umount2(zoneroot, MS_FORCE) == 0) + return (0); + err = errno; + zerror(gettext("unable to unmount zone root %s: %s"), zoneroot, + strerror(err)); + return (-1); + } + return (0); +} + int init_zfs(void) { diff --git a/usr/src/cmd/zoneadm/zoneadm.c b/usr/src/cmd/zoneadm/zoneadm.c index 058de1e7ed..af08db8d70 100644 --- a/usr/src/cmd/zoneadm/zoneadm.c +++ b/usr/src/cmd/zoneadm/zoneadm.c @@ -3488,9 +3488,9 @@ copy_zone(char *src, char *dst) } /* ARGSUSED */ -static int -zfm_print(const char *p, void *r) { - zerror(" %s\n", p); +int +zfm_print(const struct mnttab *p, void *r) { + zerror(" %s\n", p->mnt_mountp); return (0); } @@ -3951,12 +3951,14 @@ move_func(int argc, char *argv[]) zone_dochandle_t handle; boolean_t fast; boolean_t is_zfs = B_FALSE; + boolean_t root_fs_mounted = B_FALSE; struct dirent *dp; DIR *dirp; boolean_t empty = B_TRUE; boolean_t revert; struct stat zonepath_buf; struct stat new_zonepath_buf; + zone_mounts_t mounts; if (zonecfg_in_alt_root()) { zerror(gettext("cannot move zone in alternate root")); @@ -4033,13 +4035,20 @@ move_func(int argc, char *argv[]) return (Z_ERR); } - /* Don't move the zone if anything is still mounted there */ - if (zonecfg_find_mounts(zonepath, NULL, NULL)) { - zerror(gettext("These file systems are mounted on " - "subdirectories of %s.\n"), zonepath); - (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); + /* + * Collect information about mounts within the zone's zonepath. + * Overlay mounts on the zone's root directory are erroneous. + * Bail if we encounter any unexpected mounts. + */ + if (zone_mounts_init(&mounts, zonepath) != 0) return (Z_ERR); + if (mounts.num_root_overlay_mounts != 0) { + zerror(gettext("%d overlay mount(s) detected on %s/root."), + mounts.num_root_overlay_mounts, zonepath); + goto err_and_mounts_destroy; } + if (mounts.num_unexpected_mounts != 0) + goto err_and_mounts_destroy; /* * Check if we are moving in the same file system and can do a fast @@ -4049,24 +4058,29 @@ move_func(int argc, char *argv[]) if ((handle = zonecfg_init_handle()) == NULL) { zperror(cmd_to_str(CMD_MOVE), B_TRUE); - return (Z_ERR); + goto err_and_mounts_destroy; } if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { errno = err; zperror(cmd_to_str(CMD_MOVE), B_TRUE); - zonecfg_fini_handle(handle); - return (Z_ERR); + goto err_and_fini_handle; } if (zonecfg_grab_lock_file(target_zone, &lockfd) != Z_OK) { zerror(gettext("another %s may have an operation in progress."), "zoneadm"); - zonecfg_fini_handle(handle); - return (Z_ERR); + goto err_and_fini_handle; } /* + * Unmount the zone's root filesystem before we move the zone's + * zonepath. + */ + if (zone_unmount_rootfs(&mounts, zonepath, B_FALSE) != 0) + goto err_and_rele_lockfile; + + /* * We're making some file system changes now so we have to clean up * the file system before we are done. This will either clean up the * new zonepath if the zonecfg update failed or it will clean up the @@ -4088,9 +4102,8 @@ move_func(int argc, char *argv[]) if (rmdir(new_zonepath) != 0) { zperror(gettext("could not rmdir new zone path"), B_FALSE); - zonecfg_fini_handle(handle); - zonecfg_release_lock_file(target_zone, lockfd); - return (Z_ERR); + (void) zone_mount_rootfs(&mounts, zonepath); + goto err_and_rele_lockfile; } if (rename(zonepath, new_zonepath) != 0) { @@ -4100,9 +4113,8 @@ move_func(int argc, char *argv[]) * so just return from this error. */ zperror(gettext("could not move zone"), B_FALSE); - zonecfg_fini_handle(handle); - zonecfg_release_lock_file(target_zone, lockfd); - return (Z_ERR); + (void) zone_mount_rootfs(&mounts, zonepath); + goto err_and_rele_lockfile; } } else { @@ -4125,6 +4137,16 @@ move_func(int argc, char *argv[]) goto done; } + /* + * Mount the zone's root filesystem in the new zonepath if there was + * a root mount prior to the move. + */ + if (zone_mount_rootfs(&mounts, new_zonepath) != 0) { + err = Z_ERR; + goto done; + } + root_fs_mounted = B_TRUE; + if ((err = zonecfg_set_zonepath(handle, new_zonepath)) != Z_OK) { errno = err; zperror(gettext("could not set new zonepath"), B_TRUE); @@ -4149,6 +4171,24 @@ done: * or we clean up the old zonepath if everything is ok. */ if (revert) { + /* + * Check for the unlikely scenario in which the zone's + * zonepath and its root file system moved but libzonecfg + * couldn't save the new zonepath to the zone's configuration + * file. The mounted root filesystem must be unmounted before + * zoneadm restores the zone's zonepath. + */ + if (root_fs_mounted && zone_unmount_rootfs(&mounts, + new_zonepath, B_TRUE) != 0) { + /* + * We can't forcibly unmount the zone's root file system + * from the new zonepath. Bail! + */ + zerror(gettext("fatal error: cannot unmount %s/root\n"), + new_zonepath); + goto err_and_mounts_destroy; + } + /* The zonecfg update failed, cleanup the new zonepath. */ if (is_zfs) { if (move_zfs(new_zonepath, zonepath) == Z_ERR) { @@ -4158,8 +4198,9 @@ done: /* * err is already != Z_OK since we're reverting */ + } else { + (void) zone_mount_rootfs(&mounts, zonepath); } - } else if (fast) { if (rename(new_zonepath, zonepath) != 0) { zperror(gettext("could not restore zonepath"), @@ -4167,6 +4208,8 @@ done: /* * err is already != Z_OK since we're reverting */ + } else { + (void) zone_mount_rootfs(&mounts, zonepath); } } else { (void) printf(gettext("Cleaning up zonepath %s..."), @@ -4187,8 +4230,9 @@ done: */ err = Z_ERR; } - } + (void) zone_mount_rootfs(&mounts, zonepath); + } } else { /* The move was successful, cleanup the old zonepath. */ if (!is_zfs && !fast) { @@ -4206,7 +4250,16 @@ done: } } + zone_mounts_destroy(&mounts); return ((err == Z_OK) ? Z_OK : Z_ERR); + +err_and_rele_lockfile: + zonecfg_release_lock_file(target_zone, lockfd); +err_and_fini_handle: + zonecfg_fini_handle(handle); +err_and_mounts_destroy: + zone_mounts_destroy(&mounts); + return (Z_ERR); } /* ARGSUSED */ diff --git a/usr/src/cmd/zoneadm/zoneadm.h b/usr/src/cmd/zoneadm/zoneadm.h index c3506bcfc7..29c0b445ba 100644 --- a/usr/src/cmd/zoneadm/zoneadm.h +++ b/usr/src/cmd/zoneadm/zoneadm.h @@ -27,6 +27,8 @@ #ifndef _ZONEADM_H #define _ZONEADM_H +#include <sys/types.h> + #define CMD_HELP 0 #define CMD_BOOT 1 #define CMD_HALT 2 @@ -62,10 +64,46 @@ #define SW_CMP_SILENT 0x02 /* + * This structure stores information about mounts of interest within an + * installed zone. + */ +typedef struct zone_mounts { + /* The zone's zonepath */ + char *zonepath; + + /* The length of zonepath */ + int zonepath_len; + + /* + * This indicates the number of unexpected mounts that were encountered + * in the zone. + */ + int num_unexpected_mounts; + + /* + * This is the number of overlay mounts detected on the zone's root + * directory. + */ + int num_root_overlay_mounts; + + /* + * This is used to track important zone root mount information. The + * mnt_time field isn't used. If root_mnttab is NULL, then the + * associated zone doesn't have a mounted root filesystem. + * + * NOTE: mnt_mountp is non-NULL iff the zone's root filesystem is a + * ZFS filesystem with a non-legacy mountpoint. In this case, it + * refers to a string containing the dataset's mountpoint. + */ + struct mnttab *root_mnttab; +} zone_mounts_t; + +/* * zoneadm.c */ extern char *target_zone; +extern int zfm_print(const struct mnttab *mntp, void *unused); extern int clone_copy(char *source_zonepath, char *zonepath); extern char *cmd_to_str(int cmd_num); extern int do_subproc(char *cmdbuf); @@ -88,6 +126,11 @@ extern boolean_t is_zonepath_zfs(char *zonepath); extern int move_zfs(char *zonepath, char *new_zonepath); extern int verify_datasets(zone_dochandle_t handle); extern int verify_fs_zfs(struct zone_fstab *fstab); +extern int zone_mounts_init(zone_mounts_t *mounts, const char *zonepath); +extern void zone_mounts_destroy(zone_mounts_t *mounts); +extern int zone_mount_rootfs(zone_mounts_t *mounts, const char *zonepath); +extern int zone_unmount_rootfs(zone_mounts_t *mounts, const char *zonepath, + boolean_t force); extern int init_zfs(void); #endif /* _ZONEADM_H */ diff --git a/usr/src/cmd/zoneadmd/vplat.c b/usr/src/cmd/zoneadmd/vplat.c index 4911839ed6..a9722c1bd6 100644 --- a/usr/src/cmd/zoneadmd/vplat.c +++ b/usr/src/cmd/zoneadmd/vplat.c @@ -3772,8 +3772,8 @@ remove_mlps(zlog_t *zlogp, zoneid_t zoneid) } int -prtmount(const char *fs, void *x) { - zerror((zlog_t *)x, B_FALSE, " %s", fs); +prtmount(const struct mnttab *fs, void *x) { + zerror((zlog_t *)x, B_FALSE, " %s", fs->mnt_mountp); return (0); } diff --git a/usr/src/head/libzonecfg.h b/usr/src/head/libzonecfg.h index ee2b67f83c..870a8350a4 100644 --- a/usr/src/head/libzonecfg.h +++ b/usr/src/head/libzonecfg.h @@ -49,6 +49,7 @@ extern "C" { #include <libbrand.h> #include <sys/uuid.h> #include <libuutil.h> +#include <sys/mnttab.h> #define ZONE_ID_UNDEFINED -1 @@ -328,8 +329,8 @@ extern int zonecfg_lookup_ipd(zone_dochandle_t, struct zone_fstab *); extern int zonecfg_add_fs_option(struct zone_fstab *, char *); extern int zonecfg_remove_fs_option(struct zone_fstab *, char *); extern void zonecfg_free_fs_option_list(zone_fsopt_t *); -extern int zonecfg_find_mounts(char *, int(*)(const char *, void *), - void *); +extern int zonecfg_find_mounts(char *, int(*)(const struct mnttab *, + void *), void *); /* * Network interface configuration. diff --git a/usr/src/lib/brand/native/zone/sw_support.c b/usr/src/lib/brand/native/zone/sw_support.c index 7c1b083109..5747912f6a 100644 --- a/usr/src/lib/brand/native/zone/sw_support.c +++ b/usr/src/lib/brand/native/zone/sw_support.c @@ -1582,8 +1582,8 @@ get_detach_info(zone_dochandle_t handle, boolean_t detaching) /* ARGSUSED */ static int -zfm_print(const char *p, void *r) { - (void) fprintf(stderr, " %s\n", p); +zfm_print(const struct mnttab *p, void *r) { + (void) fprintf(stderr, " %s\n", p->mnt_mountp); return (0); } diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c index 9c26ef565e..d356b73701 100644 --- a/usr/src/lib/libzonecfg/common/libzonecfg.c +++ b/usr/src/lib/libzonecfg/common/libzonecfg.c @@ -2760,14 +2760,14 @@ zonecfg_devperms_apply(zone_dochandle_t hdl, const char *inpath, uid_t owner, * This function finds everything mounted under a zone's rootpath. * This returns the number of mounts under rootpath, or -1 on error. * callback is called once per mount found with the first argument - * pointing to the mount point. + * pointing to a mnttab structure containing the mount's information. * * If the callback function returns non-zero zonecfg_find_mounts * aborts with an error. */ int -zonecfg_find_mounts(char *rootpath, int (*callback)(const char *, void *), - void *priv) { +zonecfg_find_mounts(char *rootpath, int (*callback)(const struct mnttab *, + void *), void *priv) { FILE *mnttab; struct mnttab m; size_t l; @@ -2800,7 +2800,7 @@ zonecfg_find_mounts(char *rootpath, int (*callback)(const char *, void *), rv++; if (callback == NULL) continue; - if (callback(m.mnt_mountp, priv)) { + if (callback(&m, priv)) { rv = -1; goto out; |