diff options
| author | ahrens <none@none> | 2005-10-31 11:33:35 -0800 |
|---|---|---|
| committer | ahrens <none@none> | 2005-10-31 11:33:35 -0800 |
| commit | fa9e4066f08beec538e775443c5be79dd423fcab (patch) | |
| tree | 576d99665e57bb7cb70584431adb08c14d47e3ce /usr/src/cmd/zoneadmd/vplat.c | |
| parent | f1b64740276f67fc6914c1d855f2af601efe99ac (diff) | |
| download | illumos-joyent-fa9e4066f08beec538e775443c5be79dd423fcab.tar.gz | |
PSARC 2002/240 ZFS
6338653 Integrate ZFS
PSARC 2004/652 - DKIOCFLUSH
5096886 Write caching disks need mechanism to flush cache to physical media
Diffstat (limited to 'usr/src/cmd/zoneadmd/vplat.c')
| -rw-r--r-- | usr/src/cmd/zoneadmd/vplat.c | 167 |
1 files changed, 166 insertions, 1 deletions
diff --git a/usr/src/cmd/zoneadmd/vplat.c b/usr/src/cmd/zoneadmd/vplat.c index 75eca58961..98dd9e67bc 100644 --- a/usr/src/cmd/zoneadmd/vplat.c +++ b/usr/src/cmd/zoneadmd/vplat.c @@ -91,6 +91,7 @@ #include <wait.h> #include <limits.h> #include <libgen.h> +#include <libzfs.h> #include <zone.h> #include <assert.h> @@ -98,6 +99,7 @@ #include <sys/mnttab.h> #include <sys/fs/autofs.h> /* for _autofssys() */ #include <sys/fs/lofs_info.h> +#include <sys/fs/zfs.h> #include <pool.h> #include <sys/pool.h> @@ -1418,6 +1420,14 @@ mount_filesystems(zlog_t *zlogp, boolean_t mount_cmd) goto bad; } while (zonecfg_getfsent(handle, &fstab) == Z_OK) { + /* + * ZFS filesystems will not be accessible under an alternate + * root, since the pool will not be known. Ignore them in this + * case. + */ + if (mount_cmd && strcmp(fstab.zone_fs_type, MNTTYPE_ZFS) == 0) + continue; + num_fs++; if ((tmp_ptr = realloc(fs_ptr, num_fs * sizeof (*tmp_ptr))) == NULL) { @@ -2439,6 +2449,150 @@ get_zone_pool(zlog_t *zlogp, char *poolbuf, size_t bufsz) } static int +get_datasets(zlog_t *zlogp, char **bufp, size_t *bufsizep) +{ + zone_dochandle_t handle; + struct zone_dstab dstab; + size_t total, offset, len; + int error = -1; + char *str; + + *bufp = NULL; + *bufsizep = 0; + + if ((handle = zonecfg_init_handle()) == NULL) { + zerror(zlogp, B_TRUE, "getting zone configuration handle"); + return (-1); + } + if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { + zerror(zlogp, B_FALSE, "invalid configuration"); + zonecfg_fini_handle(handle); + return (-1); + } + + if (zonecfg_setdsent(handle) != Z_OK) { + zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setdsent"); + goto out; + } + + total = 0; + while (zonecfg_getdsent(handle, &dstab) == Z_OK) + total += strlen(dstab.zone_dataset_name) + 1; + (void) zonecfg_enddsent(handle); + + if (total == 0) { + error = 0; + goto out; + } + + if ((str = malloc(total)) == NULL) { + zerror(zlogp, B_TRUE, "memory allocation failed"); + goto out; + } + + if (zonecfg_setdsent(handle) != Z_OK) { + zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setdsent"); + goto out; + } + offset = 0; + while (zonecfg_getdsent(handle, &dstab) == Z_OK) { + len = strlen(dstab.zone_dataset_name); + (void) strlcpy(str + offset, dstab.zone_dataset_name, + sizeof (dstab.zone_dataset_name) - offset); + offset += len; + if (offset != total - 1) + str[offset++] = ','; + } + (void) zonecfg_enddsent(handle); + + error = 0; + *bufp = str; + *bufsizep = total; + +out: + if (error != 0 && str != NULL) + free(str); + if (handle != NULL) + zonecfg_fini_handle(handle); + + return (error); +} + +/* ARGSUSED */ +static void +zfs_error_handler(const char *fmt, va_list ap) +{ + /* + * Do nothing - we interpret the failures from each libzfs call below. + */ +} + +static int +validate_datasets(zlog_t *zlogp) +{ + zone_dochandle_t handle; + struct zone_dstab dstab; + zfs_handle_t *zhp; + + if ((handle = zonecfg_init_handle()) == NULL) { + zerror(zlogp, B_TRUE, "getting zone configuration handle"); + return (-1); + } + if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { + zerror(zlogp, B_FALSE, "invalid configuration"); + zonecfg_fini_handle(handle); + return (-1); + } + + if (zonecfg_setdsent(handle) != Z_OK) { + zerror(zlogp, B_FALSE, "invalid configuration"); + zonecfg_fini_handle(handle); + return (-1); + } + + zfs_set_error_handler(zfs_error_handler); + + /* + * libzfs opens /dev/zfs during its .init routine. + * zoneadmd automatically closes these files when it daemonizes, + * so we cheat by re-calling the init routine. + */ + zfs_init(); + + while (zonecfg_getdsent(handle, &dstab) == Z_OK) { + + if ((zhp = zfs_open(dstab.zone_dataset_name, + ZFS_TYPE_FILESYSTEM)) == NULL) { + zerror(zlogp, B_FALSE, "cannot open ZFS dataset '%s'", + dstab.zone_dataset_name); + zonecfg_fini_handle(handle); + return (-1); + } + + /* + * Automatically set the 'zoned' property. We check the value + * first because we'll get EPERM if it is already set. + */ + if (!zfs_prop_get_int(zhp, ZFS_PROP_ZONED) && + zfs_prop_set(zhp, ZFS_PROP_ZONED, "on") != 0) { + zerror(zlogp, B_FALSE, "cannot set 'zoned' " + "property for ZFS dataset '%s'\n", + dstab.zone_dataset_name); + zonecfg_fini_handle(handle); + zfs_close(zhp); + return (-1); + } + + zfs_close(zhp); + } + (void) zonecfg_enddsent(handle); + + zonecfg_fini_handle(handle); + + return (0); +} + +static int bind_to_pool(zlog_t *zlogp, zoneid_t zoneid) { pool_conf_t *poolconf; @@ -2611,6 +2765,8 @@ vplat_create(zlog_t *zlogp, boolean_t mount_cmd) char rootpath[MAXPATHLEN]; char *rctlbuf = NULL; size_t rctlbufsz = 0; + char *zfsbuf = NULL; + size_t zfsbufsz = 0; zoneid_t zoneid = -1; int xerr; char *kzone; @@ -2636,6 +2792,10 @@ vplat_create(zlog_t *zlogp, boolean_t mount_cmd) zerror(zlogp, B_FALSE, "Unable to get list of rctls"); goto error; } + if (get_datasets(zlogp, &zfsbuf, &zfsbufsz) != 0) { + zerror(zlogp, B_FALSE, "Unable to get list of ZFS datasets"); + goto error; + } kzone = zone_name; @@ -2706,7 +2866,7 @@ vplat_create(zlog_t *zlogp, boolean_t mount_cmd) xerr = 0; if ((zoneid = zone_create(kzone, rootpath, privs, rctlbuf, - rctlbufsz, &xerr)) == -1) { + rctlbufsz, zfsbuf, zfsbufsz, &xerr)) == -1) { if (xerr == ZE_AREMOUNTS) { if (zonecfg_find_mounts(rootpath, NULL, NULL) < 1) { zerror(zlogp, B_FALSE, @@ -2762,6 +2922,11 @@ error: int vplat_bringup(zlog_t *zlogp, boolean_t mount_cmd) { + if (!mount_cmd && validate_datasets(zlogp) != 0) { + lofs_discard_mnttab(); + return (-1); + } + if (create_dev_files(zlogp) != 0 || mount_filesystems(zlogp, mount_cmd) != 0) { lofs_discard_mnttab(); |
