zoneadm.c (45916cd2fec6e79bca5dee0421bd39e3c2910d1e) | zoneadm.c (0b5de56d26c0148ad33bb3a9201091502f24d910) |
---|---|
1/* 2 * CDDL HEADER START 3 * 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. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 41 unchanged lines hidden (view full) --- 50#include <string.h> 51#include <wait.h> 52#include <zone.h> 53#include <priv.h> 54#include <locale.h> 55#include <libintl.h> 56#include <libzonecfg.h> 57#include <bsm/adt.h> | 1/* 2 * CDDL HEADER START 3 * 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. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 41 unchanged lines hidden (view full) --- 50#include <string.h> 51#include <wait.h> 52#include <zone.h> 53#include <priv.h> 54#include <locale.h> 55#include <libintl.h> 56#include <libzonecfg.h> 57#include <bsm/adt.h> |
58#include <sys/utsname.h> | |
59#include <sys/param.h> 60#include <sys/types.h> 61#include <sys/stat.h> 62#include <sys/statvfs.h> 63#include <assert.h> 64#include <sys/sockio.h> 65#include <sys/mntent.h> 66#include <limits.h> | 58#include <sys/param.h> 59#include <sys/types.h> 60#include <sys/stat.h> 61#include <sys/statvfs.h> 62#include <assert.h> 63#include <sys/sockio.h> 64#include <sys/mntent.h> 65#include <limits.h> |
67#include <libzfs.h> | 66#include <dirent.h> |
68 69#include <fcntl.h> 70#include <door.h> 71#include <macros.h> 72#include <libgen.h> 73#include <fnmatch.h> 74 75#include <pool.h> 76#include <sys/pool.h> 77 | 67 68#include <fcntl.h> 69#include <door.h> 70#include <macros.h> 71#include <libgen.h> 72#include <fnmatch.h> 73 74#include <pool.h> 75#include <sys/pool.h> 76 |
77#include "zoneadm.h" 78 |
|
78#define MAXARGS 8 79 80/* Reflects kernel zone entries */ 81typedef struct zone_entry { 82 zoneid_t zid; 83 char zname[ZONENAME_MAX]; 84 char *zstate_str; 85 zone_state_t zstate_num; 86 char zroot[MAXPATHLEN]; 87} zone_entry_t; 88 89static zone_entry_t *zents; 90static size_t nzents; 91 | 79#define MAXARGS 8 80 81/* Reflects kernel zone entries */ 82typedef struct zone_entry { 83 zoneid_t zid; 84 char zname[ZONENAME_MAX]; 85 char *zstate_str; 86 zone_state_t zstate_num; 87 char zroot[MAXPATHLEN]; 88} zone_entry_t; 89 90static zone_entry_t *zents; 91static size_t nzents; 92 |
92#if !defined(TEXT_DOMAIN) /* should be defined by cc -D */ 93#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */ 94#endif 95 96#define Z_ERR 1 97#define Z_USAGE 2 98 | |
99/* 0755 is the default directory mode. */ 100#define DEFAULT_DIR_MODE \ 101 (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) 102 | 93/* 0755 is the default directory mode. */ 94#define DEFAULT_DIR_MODE \ 95 (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) 96 |
103#define CMD_HELP 0 104#define CMD_BOOT 1 105#define CMD_HALT 2 106#define CMD_READY 3 107#define CMD_REBOOT 4 108#define CMD_LIST 5 109#define CMD_VERIFY 6 110#define CMD_INSTALL 7 111#define CMD_UNINSTALL 8 112#define CMD_MOUNT 9 113#define CMD_UNMOUNT 10 114#define CMD_CLONE 11 115#define CMD_MOVE 12 116#define CMD_DETACH 13 117#define CMD_ATTACH 14 118 119#define CMD_MIN CMD_HELP 120#define CMD_MAX CMD_ATTACH 121 | |
122struct cmd { 123 uint_t cmd_num; /* command number */ 124 char *cmd_name; /* command name */ 125 char *short_usage; /* short form help */ 126 int (*handler)(int argc, char *argv[]); /* function to call */ 127 128}; 129 130#define SHELP_HELP "help" 131#define SHELP_BOOT "boot [-s]" 132#define SHELP_HALT "halt" 133#define SHELP_READY "ready" 134#define SHELP_REBOOT "reboot" 135#define SHELP_LIST "list [-cipv]" 136#define SHELP_VERIFY "verify" | 97struct cmd { 98 uint_t cmd_num; /* command number */ 99 char *cmd_name; /* command name */ 100 char *short_usage; /* short form help */ 101 int (*handler)(int argc, char *argv[]); /* function to call */ 102 103}; 104 105#define SHELP_HELP "help" 106#define SHELP_BOOT "boot [-s]" 107#define SHELP_HALT "halt" 108#define SHELP_READY "ready" 109#define SHELP_REBOOT "reboot" 110#define SHELP_LIST "list [-cipv]" 111#define SHELP_VERIFY "verify" |
137#define SHELP_INSTALL "install" | 112#define SHELP_INSTALL "install [-x nodataset]" |
138#define SHELP_UNINSTALL "uninstall [-F]" | 113#define SHELP_UNINSTALL "uninstall [-F]" |
139#define SHELP_CLONE "clone [-m method] zonename" | 114#define SHELP_CLONE "clone [-m method] [-s <ZFS snapshot>] zonename" |
140#define SHELP_MOVE "move zonepath" 141#define SHELP_DETACH "detach" 142#define SHELP_ATTACH "attach [-F]" 143 144static int help_func(int argc, char *argv[]); 145static int ready_func(int argc, char *argv[]); 146static int boot_func(int argc, char *argv[]); 147static int halt_func(int argc, char *argv[]); --- 32 unchanged lines hidden (view full) --- 180 { CMD_DETACH, "detach", SHELP_DETACH, detach_func }, 181 { CMD_ATTACH, "attach", SHELP_ATTACH, attach_func } 182}; 183 184/* global variables */ 185 186/* set early in main(), never modified thereafter, used all over the place */ 187static char *execname; | 115#define SHELP_MOVE "move zonepath" 116#define SHELP_DETACH "detach" 117#define SHELP_ATTACH "attach [-F]" 118 119static int help_func(int argc, char *argv[]); 120static int ready_func(int argc, char *argv[]); 121static int boot_func(int argc, char *argv[]); 122static int halt_func(int argc, char *argv[]); --- 32 unchanged lines hidden (view full) --- 155 { CMD_DETACH, "detach", SHELP_DETACH, detach_func }, 156 { CMD_ATTACH, "attach", SHELP_ATTACH, attach_func } 157}; 158 159/* global variables */ 160 161/* set early in main(), never modified thereafter, used all over the place */ 162static char *execname; |
188static char *target_zone; | |
189static char *locale; | 163static char *locale; |
164char *target_zone; |
|
190 191/* used in do_subproc() and signal handler */ 192static volatile boolean_t child_killed; 193 | 165 166/* used in do_subproc() and signal handler */ 167static volatile boolean_t child_killed; 168 |
194static char * | 169char * |
195cmd_to_str(int cmd_num) 196{ 197 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX); 198 return (cmdtab[cmd_num].cmd_name); 199} 200 201/* This is a separate function because of gettext() wrapping. */ 202static char * --- 32 unchanged lines hidden (view full) --- 235 "machine-parsable output. The -v\n\tand -p " 236 "options are mutually exclusive. If neither -v " 237 "nor -p is used,\n\tjust the zone name is listed.")); 238 case CMD_VERIFY: 239 return (gettext("Check to make sure the configuration " 240 "can safely be instantiated\n\ton the machine: " 241 "physical network interfaces exist, etc.")); 242 case CMD_INSTALL: | 170cmd_to_str(int cmd_num) 171{ 172 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX); 173 return (cmdtab[cmd_num].cmd_name); 174} 175 176/* This is a separate function because of gettext() wrapping. */ 177static char * --- 32 unchanged lines hidden (view full) --- 210 "machine-parsable output. The -v\n\tand -p " 211 "options are mutually exclusive. If neither -v " 212 "nor -p is used,\n\tjust the zone name is listed.")); 213 case CMD_VERIFY: 214 return (gettext("Check to make sure the configuration " 215 "can safely be instantiated\n\ton the machine: " 216 "physical network interfaces exist, etc.")); 217 case CMD_INSTALL: |
243 return (gettext("Install the configuration on to the system.")); | 218 return (gettext("Install the configuration on to the system. " 219 "The -x nodataset option\n\tcan be used to prevent the " 220 "creation of a new ZFS file system for the\n\tzone " 221 "(assuming the zonepath is within a ZFS file system).")); |
244 case CMD_UNINSTALL: 245 return (gettext("Uninstall the configuration from the system. " 246 "The -F flag can be used\n\tto force the action.")); 247 case CMD_CLONE: | 222 case CMD_UNINSTALL: 223 return (gettext("Uninstall the configuration from the system. " 224 "The -F flag can be used\n\tto force the action.")); 225 case CMD_CLONE: |
248 return (gettext("Clone the installation of another zone.")); | 226 return (gettext("Clone the installation of another zone. " 227 "The -m option can be used to\n\tspecify 'copy' which " 228 "forces a copy of the source zone. The -s option\n\t" 229 "can be used to specify the name of a ZFS snapshot " 230 "that was taken from\n\ta previous clone command. The " 231 "snapshot will be used as the source\n\tinstead of " 232 "creating a new ZFS snapshot.")); |
249 case CMD_MOVE: 250 return (gettext("Move the zone to a new zonepath.")); 251 case CMD_DETACH: 252 return (gettext("Detach the zone from the system. The zone " 253 "state is changed to\n\t'configured' (but the files under " 254 "the zonepath are untouched).\n\tThe zone can subsequently " 255 "be attached, or can be moved to another\n\tsystem and " 256 "attached there.")); --- 48 unchanged lines hidden (view full) --- 305} 306 307/* 308 * zperror() is like perror(3c) except that this also prints the executable 309 * name at the start of the message, and takes a boolean indicating whether 310 * to call libc'c strerror() or that from libzonecfg. 311 */ 312 | 233 case CMD_MOVE: 234 return (gettext("Move the zone to a new zonepath.")); 235 case CMD_DETACH: 236 return (gettext("Detach the zone from the system. The zone " 237 "state is changed to\n\t'configured' (but the files under " 238 "the zonepath are untouched).\n\tThe zone can subsequently " 239 "be attached, or can be moved to another\n\tsystem and " 240 "attached there.")); --- 48 unchanged lines hidden (view full) --- 289} 290 291/* 292 * zperror() is like perror(3c) except that this also prints the executable 293 * name at the start of the message, and takes a boolean indicating whether 294 * to call libc'c strerror() or that from libzonecfg. 295 */ 296 |
313static void | 297void |
314zperror(const char *str, boolean_t zonecfg_error) 315{ 316 (void) fprintf(stderr, "%s: %s: %s\n", execname, str, 317 zonecfg_error ? zonecfg_strerror(errno) : strerror(errno)); 318} 319 320/* 321 * zperror2() is very similar to zperror() above, except it also prints a 322 * supplied zone name after the executable. 323 * 324 * All current consumers of this function want libzonecfg's strerror() rather 325 * than libc's; if this ever changes, this function can be made more generic 326 * like zperror() above. 327 */ 328 | 298zperror(const char *str, boolean_t zonecfg_error) 299{ 300 (void) fprintf(stderr, "%s: %s: %s\n", execname, str, 301 zonecfg_error ? zonecfg_strerror(errno) : strerror(errno)); 302} 303 304/* 305 * zperror2() is very similar to zperror() above, except it also prints a 306 * supplied zone name after the executable. 307 * 308 * All current consumers of this function want libzonecfg's strerror() rather 309 * than libc's; if this ever changes, this function can be made more generic 310 * like zperror() above. 311 */ 312 |
329static void | 313void |
330zperror2(const char *zone, const char *str) 331{ 332 (void) fprintf(stderr, "%s: %s: %s: %s\n", execname, zone, str, 333 zonecfg_strerror(errno)); 334} 335 336/* PRINTFLIKE1 */ | 314zperror2(const char *zone, const char *str) 315{ 316 (void) fprintf(stderr, "%s: %s: %s: %s\n", execname, zone, str, 317 zonecfg_strerror(errno)); 318} 319 320/* PRINTFLIKE1 */ |
337static void | 321void |
338zerror(const char *fmt, ...) 339{ 340 va_list alist; 341 342 va_start(alist, fmt); 343 (void) fprintf(stderr, "%s: ", execname); 344 if (target_zone != NULL) 345 (void) fprintf(stderr, "zone '%s': ", target_zone); --- 496 unchanged lines hidden (view full) --- 842 if (!S_ISDIR(stbuf.st_mode)) { 843 (void) fprintf(stderr, gettext("%s is not a directory.\n"), 844 rpath); 845 return (Z_ERR); 846 } 847 if ((strcmp(stbuf.st_fstype, MNTTYPE_TMPFS) == 0) || 848 (strcmp(stbuf.st_fstype, MNTTYPE_XMEMFS) == 0)) { 849 (void) printf(gettext("WARNING: %s is on a temporary " | 322zerror(const char *fmt, ...) 323{ 324 va_list alist; 325 326 va_start(alist, fmt); 327 (void) fprintf(stderr, "%s: ", execname); 328 if (target_zone != NULL) 329 (void) fprintf(stderr, "zone '%s': ", target_zone); --- 496 unchanged lines hidden (view full) --- 826 if (!S_ISDIR(stbuf.st_mode)) { 827 (void) fprintf(stderr, gettext("%s is not a directory.\n"), 828 rpath); 829 return (Z_ERR); 830 } 831 if ((strcmp(stbuf.st_fstype, MNTTYPE_TMPFS) == 0) || 832 (strcmp(stbuf.st_fstype, MNTTYPE_XMEMFS) == 0)) { 833 (void) printf(gettext("WARNING: %s is on a temporary " |
850 "file-system.\n"), rpath); | 834 "file system.\n"), rpath); |
851 } 852 if (crosscheck_zonepaths(rpath) != Z_OK) 853 return (Z_ERR); 854 /* 855 * Try to collect and report as many minor errors as possible 856 * before returning, so the user can learn everything that needs 857 * to be fixed up front. 858 */ --- 49 unchanged lines hidden (view full) --- 908 return (Z_ERR); 909 } 910 if (strcmp(vfsbuf.f_basetype, MNTTYPE_NFS) == 0) { 911 /* 912 * TRANSLATION_NOTE 913 * Zonepath and NFS are literals that should not be translated. 914 */ 915 (void) fprintf(stderr, gettext("Zonepath %s is on an NFS " | 835 } 836 if (crosscheck_zonepaths(rpath) != Z_OK) 837 return (Z_ERR); 838 /* 839 * Try to collect and report as many minor errors as possible 840 * before returning, so the user can learn everything that needs 841 * to be fixed up front. 842 */ --- 49 unchanged lines hidden (view full) --- 892 return (Z_ERR); 893 } 894 if (strcmp(vfsbuf.f_basetype, MNTTYPE_NFS) == 0) { 895 /* 896 * TRANSLATION_NOTE 897 * Zonepath and NFS are literals that should not be translated. 898 */ 899 (void) fprintf(stderr, gettext("Zonepath %s is on an NFS " |
916 "mounted file-system.\n" 917 "\tA local file-system must be used.\n"), rpath); | 900 "mounted file system.\n" 901 "\tA local file system must be used.\n"), rpath); |
918 return (Z_ERR); 919 } 920 if (vfsbuf.f_flag & ST_NOSUID) { 921 /* 922 * TRANSLATION_NOTE 923 * Zonepath and nosuid are literals that should not be 924 * translated. 925 */ 926 (void) fprintf(stderr, gettext("Zonepath %s is on a nosuid " | 902 return (Z_ERR); 903 } 904 if (vfsbuf.f_flag & ST_NOSUID) { 905 /* 906 * TRANSLATION_NOTE 907 * Zonepath and nosuid are literals that should not be 908 * translated. 909 */ 910 (void) fprintf(stderr, gettext("Zonepath %s is on a nosuid " |
927 "file-system.\n"), rpath); | 911 "file system.\n"), rpath); |
928 return (Z_ERR); 929 } 930 931 if ((res = zone_get_state(target_zone, &state)) != Z_OK) { 932 errno = res; 933 zperror2(target_zone, gettext("could not get state")); 934 return (Z_ERR); 935 } --- 1032 unchanged lines hidden (view full) --- 1968 } 1969 if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) { 1970 /* 1971 * TRANSLATION_NOTE 1972 * inherit-pkg-dir and NFS are literals that should 1973 * not be translated. 1974 */ 1975 (void) fprintf(stderr, gettext("cannot verify " | 912 return (Z_ERR); 913 } 914 915 if ((res = zone_get_state(target_zone, &state)) != Z_OK) { 916 errno = res; 917 zperror2(target_zone, gettext("could not get state")); 918 return (Z_ERR); 919 } --- 1032 unchanged lines hidden (view full) --- 1952 } 1953 if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) { 1954 /* 1955 * TRANSLATION_NOTE 1956 * inherit-pkg-dir and NFS are literals that should 1957 * not be translated. 1958 */ 1959 (void) fprintf(stderr, gettext("cannot verify " |
1976 "inherit-pkg-dir %s: NFS mounted file-system.\n" 1977 "\tA local file-system must be used.\n"), | 1960 "inherit-pkg-dir %s: NFS mounted file system.\n" 1961 "\tA local file system must be used.\n"), |
1978 fstab.zone_fs_dir); 1979 return_code = Z_ERR; 1980 } 1981 } 1982 (void) zonecfg_endipdent(handle); 1983 1984 return (return_code); 1985} 1986 | 1962 fstab.zone_fs_dir); 1963 return_code = Z_ERR; 1964 } 1965 } 1966 (void) zonecfg_endipdent(handle); 1967 1968 return (return_code); 1969} 1970 |
1987/* ARGSUSED */ 1988static void 1989zfs_fs_err_handler(const char *fmt, va_list ap) 1990{ 1991 /* 1992 * Do nothing - do not print the libzfs error messages. 1993 */ 1994} 1995 | |
1996/* | 1971/* |
1997 * Verify that the ZFS dataset exists, and its mountpoint 1998 * property is set to "legacy". | 1972 * Verify that the special device/file system exists and is valid. |
1999 */ 2000static int | 1973 */ 1974static int |
2001verify_fs_zfs(struct zone_fstab *fstab) 2002{ 2003 zfs_handle_t *zhp; 2004 char propbuf[ZFS_MAXPROPLEN]; 2005 2006 zfs_set_error_handler(zfs_fs_err_handler); 2007 2008 if ((zhp = zfs_open(fstab->zone_fs_special, ZFS_TYPE_ANY)) == NULL) { 2009 (void) fprintf(stderr, gettext("could not verify fs %s: " 2010 "could not access zfs dataset '%s'\n"), 2011 fstab->zone_fs_dir, fstab->zone_fs_special); 2012 return (Z_ERR); 2013 } 2014 2015 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) { 2016 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2017 "'%s' is not a filesystem\n"), 2018 fstab->zone_fs_dir, fstab->zone_fs_special); 2019 zfs_close(zhp); 2020 return (Z_ERR); 2021 } 2022 2023 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, propbuf, sizeof (propbuf), 2024 NULL, NULL, 0, 0) != 0 || strcmp(propbuf, "legacy") != 0) { 2025 (void) fprintf(stderr, gettext("could not verify fs %s: " 2026 "zfs '%s' mountpoint is not \"legacy\"\n"), 2027 fstab->zone_fs_dir, fstab->zone_fs_special); 2028 zfs_close(zhp); 2029 return (Z_ERR); 2030 } 2031 2032 zfs_close(zhp); 2033 return (Z_OK); 2034} 2035 2036/* 2037 * Verify that the special device/filesystem exists and is valid. 2038 */ 2039static int | |
2040verify_fs_special(struct zone_fstab *fstab) 2041{ 2042 struct stat st; 2043 2044 if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0) 2045 return (verify_fs_zfs(fstab)); 2046 2047 if (stat(fstab->zone_fs_special, &st) != 0) { --- 5 unchanged lines hidden (view full) --- 2053 2054 if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) { 2055 /* 2056 * TRANSLATION_NOTE 2057 * fs and NFS are literals that should 2058 * not be translated. 2059 */ 2060 (void) fprintf(stderr, gettext("cannot verify " | 1975verify_fs_special(struct zone_fstab *fstab) 1976{ 1977 struct stat st; 1978 1979 if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0) 1980 return (verify_fs_zfs(fstab)); 1981 1982 if (stat(fstab->zone_fs_special, &st) != 0) { --- 5 unchanged lines hidden (view full) --- 1988 1989 if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) { 1990 /* 1991 * TRANSLATION_NOTE 1992 * fs and NFS are literals that should 1993 * not be translated. 1994 */ 1995 (void) fprintf(stderr, gettext("cannot verify " |
2061 "fs %s: NFS mounted file-system.\n" 2062 "\tA local file-system must be used.\n"), | 1996 "fs %s: NFS mounted file system.\n" 1997 "\tA local file system must be used.\n"), |
2063 fstab->zone_fs_special); 2064 return (Z_ERR); 2065 } 2066 2067 return (Z_OK); 2068} 2069 2070static int 2071verify_filesystems(zone_dochandle_t handle) 2072{ 2073 int return_code = Z_OK; 2074 struct zone_fstab fstab; 2075 char cmdbuf[MAXPATHLEN]; 2076 struct stat st; 2077 2078 /* 2079 * No need to verify inherit-pkg-dir fs types, as their type is 2080 * implicitly lofs, which is known. Therefore, the types are only | 1998 fstab->zone_fs_special); 1999 return (Z_ERR); 2000 } 2001 2002 return (Z_OK); 2003} 2004 2005static int 2006verify_filesystems(zone_dochandle_t handle) 2007{ 2008 int return_code = Z_OK; 2009 struct zone_fstab fstab; 2010 char cmdbuf[MAXPATHLEN]; 2011 struct stat st; 2012 2013 /* 2014 * No need to verify inherit-pkg-dir fs types, as their type is 2015 * implicitly lofs, which is known. Therefore, the types are only |
2081 * verified for regular filesystems below. | 2016 * verified for regular file systems below. |
2082 * 2083 * Since the actual mount point is not known until the dependent mounts 2084 * are performed, we don't attempt any path validation here: that will 2085 * happen later when zoneadmd actually does the mounts. 2086 */ 2087 if (zonecfg_setfsent(handle) != Z_OK) { | 2017 * 2018 * Since the actual mount point is not known until the dependent mounts 2019 * are performed, we don't attempt any path validation here: that will 2020 * happen later when zoneadmd actually does the mounts. 2021 */ 2022 if (zonecfg_setfsent(handle) != Z_OK) { |
2088 (void) fprintf(stderr, gettext("could not verify file-systems: " | 2023 (void) fprintf(stderr, gettext("could not verify file systems: " |
2089 "unable to enumerate mounts\n")); 2090 return (Z_ERR); 2091 } 2092 while (zonecfg_getfsent(handle, &fstab) == Z_OK) { 2093 if (!zonecfg_valid_fs_type(fstab.zone_fs_type)) { 2094 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2095 "type %s is not allowed.\n"), fstab.zone_fs_dir, 2096 fstab.zone_fs_type); --- 35 unchanged lines hidden (view full) --- 2132 "type %s is too long.\n"), fstab.zone_fs_dir, 2133 fstab.zone_fs_type); 2134 return_code = Z_ERR; 2135 goto next_fs; 2136 } 2137 if (fstab.zone_fs_raw[0] == '\0' && stat(cmdbuf, &st) == 0) { 2138 (void) fprintf(stderr, gettext("could not verify fs " 2139 "%s: must specify 'raw' device for %s " | 2024 "unable to enumerate mounts\n")); 2025 return (Z_ERR); 2026 } 2027 while (zonecfg_getfsent(handle, &fstab) == Z_OK) { 2028 if (!zonecfg_valid_fs_type(fstab.zone_fs_type)) { 2029 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2030 "type %s is not allowed.\n"), fstab.zone_fs_dir, 2031 fstab.zone_fs_type); --- 35 unchanged lines hidden (view full) --- 2067 "type %s is too long.\n"), fstab.zone_fs_dir, 2068 fstab.zone_fs_type); 2069 return_code = Z_ERR; 2070 goto next_fs; 2071 } 2072 if (fstab.zone_fs_raw[0] == '\0' && stat(cmdbuf, &st) == 0) { 2073 (void) fprintf(stderr, gettext("could not verify fs " 2074 "%s: must specify 'raw' device for %s " |
2140 "file-systems\n"), | 2075 "file systems\n"), |
2141 fstab.zone_fs_dir, fstab.zone_fs_type); 2142 return_code = Z_ERR; 2143 goto next_fs; 2144 } 2145 if (fstab.zone_fs_raw[0] != '\0' && 2146 (stat(cmdbuf, &st) != 0 || !S_ISREG(st.st_mode))) { 2147 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2148 "'raw' device specified but " --- 23 unchanged lines hidden (view full) --- 2172next_fs: 2173 zonecfg_free_fs_option_list(fstab.zone_fs_options); 2174 } 2175 (void) zonecfg_endfsent(handle); 2176 2177 return (return_code); 2178} 2179 | 2076 fstab.zone_fs_dir, fstab.zone_fs_type); 2077 return_code = Z_ERR; 2078 goto next_fs; 2079 } 2080 if (fstab.zone_fs_raw[0] != '\0' && 2081 (stat(cmdbuf, &st) != 0 || !S_ISREG(st.st_mode))) { 2082 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2083 "'raw' device specified but " --- 23 unchanged lines hidden (view full) --- 2107next_fs: 2108 zonecfg_free_fs_option_list(fstab.zone_fs_options); 2109 } 2110 (void) zonecfg_endfsent(handle); 2111 2112 return (return_code); 2113} 2114 |
2180const char *current_dataset; 2181 2182/* 2183 * Custom error handler for errors incurred as part of the checks below. We 2184 * want to trim off the leading 'cannot open ...' to create a better error 2185 * message. The only other way this can fail is if we fail to set the 'zoned' 2186 * property. In this case we just pass the error on verbatim. 2187 */ 2188static void 2189zfs_error_handler(const char *fmt, va_list ap) 2190{ 2191 char buf[1024]; 2192 2193 (void) vsnprintf(buf, sizeof (buf), fmt, ap); 2194 2195 if (strncmp(gettext("cannot open "), buf, 2196 strlen(gettext("cannot open "))) == 0) 2197 /* 2198 * TRANSLATION_NOTE 2199 * zfs and dataset are literals that should not be translated. 2200 */ 2201 (void) fprintf(stderr, gettext("could not verify zfs " 2202 "dataset %s%s\n"), current_dataset, strchr(buf, ':')); 2203 else 2204 (void) fprintf(stderr, gettext("could not verify zfs dataset " 2205 "%s: %s\n"), current_dataset, buf); 2206} 2207 2208/* ARGSUSED */ | |
2209static int | 2115static int |
2210check_zvol(zfs_handle_t *zhp, void *unused) 2211{ 2212 int ret; 2213 2214 if (zfs_get_type(zhp) == ZFS_TYPE_VOLUME) { 2215 /* 2216 * TRANSLATION_NOTE 2217 * zfs and dataset are literals that should not be translated. 2218 */ 2219 (void) fprintf(stderr, gettext("cannot verify zfs dataset %s: " 2220 "volumes cannot be specified as a zone dataset resource\n"), 2221 zfs_get_name(zhp)); 2222 ret = -1; 2223 } else { 2224 ret = zfs_iter_children(zhp, check_zvol, NULL); 2225 } 2226 2227 zfs_close(zhp); 2228 2229 return (ret); 2230} 2231 2232/* 2233 * Validate that the given dataset exists on the system, and that neither it nor 2234 * its children are zvols. 2235 * 2236 * Note that we don't do anything with the 'zoned' property here. All 2237 * management is done in zoneadmd when the zone is actually rebooted. This 2238 * allows us to automatically set the zoned property even when a zone is 2239 * rebooted by the administrator. 2240 */ 2241static int 2242verify_datasets(zone_dochandle_t handle) 2243{ 2244 int return_code = Z_OK; 2245 struct zone_dstab dstab; 2246 zfs_handle_t *zhp; 2247 char propbuf[ZFS_MAXPROPLEN]; 2248 char source[ZFS_MAXNAMELEN]; 2249 zfs_source_t srctype; 2250 2251 if (zonecfg_setdsent(handle) != Z_OK) { 2252 /* 2253 * TRANSLATION_NOTE 2254 * zfs and dataset are literals that should not be translated. 2255 */ 2256 (void) fprintf(stderr, gettext("could not verify zfs datasets: " 2257 "unable to enumerate datasets\n")); 2258 return (Z_ERR); 2259 } 2260 2261 zfs_set_error_handler(zfs_error_handler); 2262 2263 while (zonecfg_getdsent(handle, &dstab) == Z_OK) { 2264 2265 current_dataset = dstab.zone_dataset_name; 2266 2267 if ((zhp = zfs_open(dstab.zone_dataset_name, 2268 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) { 2269 return_code = Z_ERR; 2270 continue; 2271 } 2272 2273 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, propbuf, 2274 sizeof (propbuf), &srctype, source, 2275 sizeof (source), 0) == 0 && 2276 (srctype == ZFS_SRC_INHERITED)) { 2277 (void) fprintf(stderr, gettext("could not verify zfs " 2278 "dataset %s: mountpoint cannot be inherited\n"), 2279 dstab.zone_dataset_name); 2280 return_code = Z_ERR; 2281 zfs_close(zhp); 2282 continue; 2283 } 2284 2285 if (zfs_get_type(zhp) == ZFS_TYPE_VOLUME) { 2286 (void) fprintf(stderr, gettext("cannot verify zfs " 2287 "dataset %s: volumes cannot be specified as a " 2288 "zone dataset resource\n"), 2289 dstab.zone_dataset_name); 2290 return_code = Z_ERR; 2291 } 2292 2293 if (zfs_iter_children(zhp, check_zvol, NULL) != 0) 2294 return_code = Z_ERR; 2295 2296 zfs_close(zhp); 2297 } 2298 (void) zonecfg_enddsent(handle); 2299 2300 return (return_code); 2301} 2302 2303static int | |
2304verify_limitpriv(zone_dochandle_t handle) 2305{ 2306 char *privname = NULL; 2307 int err; 2308 priv_set_t *privs; 2309 2310 if ((privs = priv_allocset()) == NULL) { 2311 zperror(gettext("failed to allocate privilege set"), B_FALSE); --- 194 unchanged lines hidden (view full) --- 2506install_func(int argc, char *argv[]) 2507{ 2508 /* 9: "exec " and " -z " */ 2509 char cmdbuf[sizeof (LUCREATEZONE) + ZONENAME_MAX + 9]; 2510 int lockfd; 2511 int err, arg; 2512 char zonepath[MAXPATHLEN]; 2513 int status; | 2116verify_limitpriv(zone_dochandle_t handle) 2117{ 2118 char *privname = NULL; 2119 int err; 2120 priv_set_t *privs; 2121 2122 if ((privs = priv_allocset()) == NULL) { 2123 zperror(gettext("failed to allocate privilege set"), B_FALSE); --- 194 unchanged lines hidden (view full) --- 2318install_func(int argc, char *argv[]) 2319{ 2320 /* 9: "exec " and " -z " */ 2321 char cmdbuf[sizeof (LUCREATEZONE) + ZONENAME_MAX + 9]; 2322 int lockfd; 2323 int err, arg; 2324 char zonepath[MAXPATHLEN]; 2325 int status; |
2326 boolean_t nodataset = B_FALSE; |
|
2514 2515 if (zonecfg_in_alt_root()) { 2516 zerror(gettext("cannot install zone in alternate root")); 2517 return (Z_ERR); 2518 } 2519 2520 optind = 0; | 2327 2328 if (zonecfg_in_alt_root()) { 2329 zerror(gettext("cannot install zone in alternate root")); 2330 return (Z_ERR); 2331 } 2332 2333 optind = 0; |
2521 if ((arg = getopt(argc, argv, "?")) != EOF) { | 2334 if ((arg = getopt(argc, argv, "?x:")) != EOF) { |
2522 switch (arg) { 2523 case '?': 2524 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2525 return (optopt == '?' ? Z_OK : Z_USAGE); | 2335 switch (arg) { 2336 case '?': 2337 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2338 return (optopt == '?' ? Z_OK : Z_USAGE); |
2339 case 'x': 2340 if (strcmp(optarg, "nodataset") != 0) { 2341 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2342 return (Z_USAGE); 2343 } 2344 nodataset = B_TRUE; 2345 break; |
|
2526 default: 2527 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2528 return (Z_USAGE); 2529 } 2530 } 2531 if (argc > optind) { 2532 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2533 return (Z_USAGE); --- 26 unchanged lines hidden (view full) --- 2560 * path to the zone is again restricted. 2561 */ 2562 if ((err = zone_get_zonepath(target_zone, zonepath, 2563 sizeof (zonepath))) != Z_OK) { 2564 errno = err; 2565 zperror2(target_zone, gettext("could not get zone path")); 2566 goto done; 2567 } | 2346 default: 2347 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2348 return (Z_USAGE); 2349 } 2350 } 2351 if (argc > optind) { 2352 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2353 return (Z_USAGE); --- 26 unchanged lines hidden (view full) --- 2380 * path to the zone is again restricted. 2381 */ 2382 if ((err = zone_get_zonepath(target_zone, zonepath, 2383 sizeof (zonepath))) != Z_OK) { 2384 errno = err; 2385 zperror2(target_zone, gettext("could not get zone path")); 2386 goto done; 2387 } |
2388 2389 if (!nodataset) 2390 create_zfs_zonepath(zonepath); 2391 |
|
2568 if (chmod(zonepath, DEFAULT_DIR_MODE) != 0) { 2569 zperror(zonepath, B_FALSE); 2570 err = Z_ERR; 2571 goto done; 2572 } 2573 2574 /* 2575 * "exec" the command so that the returned status is that of --- 174 unchanged lines hidden (view full) --- 2750 if (strcmp(p, opt) == 0) 2751 return (B_TRUE); 2752 } 2753 } 2754 2755 return (B_FALSE); 2756} 2757 | 2392 if (chmod(zonepath, DEFAULT_DIR_MODE) != 0) { 2393 zperror(zonepath, B_FALSE); 2394 err = Z_ERR; 2395 goto done; 2396 } 2397 2398 /* 2399 * "exec" the command so that the returned status is that of --- 174 unchanged lines hidden (view full) --- 2574 if (strcmp(p, opt) == 0) 2575 return (B_TRUE); 2576 } 2577 } 2578 2579 return (B_FALSE); 2580} 2581 |
2758#define RW_LOFS "WARNING: read-write lofs file-system on '%s' is configured " \ | 2582#define RW_LOFS "WARNING: read-write lofs file system on '%s' is configured " \ |
2759 "in both zones.\n" 2760 2761static void 2762print_fs_warnings(struct zone_fstab *s_fstab, struct zone_fstab *t_fstab) 2763{ 2764 /* 2765 * It is ok to have shared lofs mounted fs but we want to warn if 2766 * either is rw since this will effect the other zone. --- 27 unchanged lines hidden (view full) --- 2794 } 2795 } 2796 2797 return; 2798 } 2799 2800 /* 2801 * TRANSLATION_NOTE | 2583 "in both zones.\n" 2584 2585static void 2586print_fs_warnings(struct zone_fstab *s_fstab, struct zone_fstab *t_fstab) 2587{ 2588 /* 2589 * It is ok to have shared lofs mounted fs but we want to warn if 2590 * either is rw since this will effect the other zone. --- 27 unchanged lines hidden (view full) --- 2618 } 2619 } 2620 2621 return; 2622 } 2623 2624 /* 2625 * TRANSLATION_NOTE |
2802 * The first variable is the file-system type and the second is 2803 * the file-system special device. For example, 2804 * WARNING: ufs file-system on '/dev/dsk/c0t0d0s0' ... | 2626 * The first variable is the file system type and the second is 2627 * the file system special device. For example, 2628 * WARNING: ufs file system on '/dev/dsk/c0t0d0s0' ... |
2805 */ | 2629 */ |
2806 (void) fprintf(stderr, gettext("WARNING: %s file-system on '%s' " | 2630 (void) fprintf(stderr, gettext("WARNING: %s file system on '%s' " |
2807 "is configured in both zones.\n"), t_fstab->zone_fs_type, 2808 t_fstab->zone_fs_special); 2809} 2810 2811static void 2812warn_fs_match(zone_dochandle_t s_handle, char *source_zone, 2813 zone_dochandle_t t_handle, char *target_zone) 2814{ 2815 int err; 2816 struct zone_fstab s_fstab; 2817 struct zone_fstab t_fstab; 2818 2819 if ((err = zonecfg_setfsent(t_handle)) != Z_OK) { 2820 errno = err; 2821 zperror2(target_zone, | 2631 "is configured in both zones.\n"), t_fstab->zone_fs_type, 2632 t_fstab->zone_fs_special); 2633} 2634 2635static void 2636warn_fs_match(zone_dochandle_t s_handle, char *source_zone, 2637 zone_dochandle_t t_handle, char *target_zone) 2638{ 2639 int err; 2640 struct zone_fstab s_fstab; 2641 struct zone_fstab t_fstab; 2642 2643 if ((err = zonecfg_setfsent(t_handle)) != Z_OK) { 2644 errno = err; 2645 zperror2(target_zone, |
2822 gettext("could not enumerate file-systems")); | 2646 gettext("could not enumerate file systems")); |
2823 return; 2824 } 2825 2826 while (zonecfg_getfsent(t_handle, &t_fstab) == Z_OK) { 2827 if ((err = zonecfg_setfsent(s_handle)) != Z_OK) { 2828 errno = err; 2829 zperror2(source_zone, | 2647 return; 2648 } 2649 2650 while (zonecfg_getfsent(t_handle, &t_fstab) == Z_OK) { 2651 if ((err = zonecfg_setfsent(s_handle)) != Z_OK) { 2652 errno = err; 2653 zperror2(source_zone, |
2830 gettext("could not enumerate file-systems")); | 2654 gettext("could not enumerate file systems")); |
2831 (void) zonecfg_endfsent(t_handle); 2832 return; 2833 } 2834 2835 while (zonecfg_getfsent(s_handle, &s_fstab) == Z_OK) { 2836 if (strcmp(t_fstab.zone_fs_special, 2837 s_fstab.zone_fs_special) == 0) { 2838 print_fs_warnings(&s_fstab, &t_fstab); --- 163 unchanged lines hidden (view full) --- 3002 char *outfile; 3003 char cmdbuf[MAXPATHLEN * 2 + 128]; 3004 3005 if ((outfile = tempnam("/var/log", "zone")) == NULL) { 3006 outfile = "/dev/null"; 3007 out_null = B_TRUE; 3008 } 3009 | 2655 (void) zonecfg_endfsent(t_handle); 2656 return; 2657 } 2658 2659 while (zonecfg_getfsent(s_handle, &s_fstab) == Z_OK) { 2660 if (strcmp(t_fstab.zone_fs_special, 2661 s_fstab.zone_fs_special) == 0) { 2662 print_fs_warnings(&s_fstab, &t_fstab); --- 163 unchanged lines hidden (view full) --- 2826 char *outfile; 2827 char cmdbuf[MAXPATHLEN * 2 + 128]; 2828 2829 if ((outfile = tempnam("/var/log", "zone")) == NULL) { 2830 outfile = "/dev/null"; 2831 out_null = B_TRUE; 2832 } 2833 |
2834 /* 2835 * Use find to get the list of files to copy. We need to skip 2836 * files of type "socket" since cpio can't handle those but that 2837 * should be ok since the app will recreate the socket when it runs. 2838 * We also need to filter out anything under the .zfs subdir. Since 2839 * find is running depth-first, we need the extra egrep to filter .zfs. 2840 */ |
|
3010 (void) snprintf(cmdbuf, sizeof (cmdbuf), | 2841 (void) snprintf(cmdbuf, sizeof (cmdbuf), |
3011 "cd %s && /usr/bin/find . -depth -print | " | 2842 "cd %s && /usr/bin/find . -type s -prune -o -depth -print | " |
3012 "/usr/bin/egrep -v '^\\./\\.zfs$|^\\./\\.zfs/' | " 3013 "/usr/bin/cpio -pdmuP@ %s > %s 2>&1", 3014 src, dst, outfile); 3015 3016 status = do_subproc(cmdbuf); 3017 3018 if ((err = subproc_status("copy", status)) != Z_OK) { 3019 if (!out_null) --- 68 unchanged lines hidden (view full) --- 3088 (void) fprintf(stderr, gettext("could not unmount zone\n")); 3089 return (Z_ERR); 3090 } 3091 3092 return ((err == Z_OK) ? Z_OK : Z_ERR); 3093} 3094 3095/* ARGSUSED */ | 2843 "/usr/bin/egrep -v '^\\./\\.zfs$|^\\./\\.zfs/' | " 2844 "/usr/bin/cpio -pdmuP@ %s > %s 2>&1", 2845 src, dst, outfile); 2846 2847 status = do_subproc(cmdbuf); 2848 2849 if ((err = subproc_status("copy", status)) != Z_OK) { 2850 if (!out_null) --- 68 unchanged lines hidden (view full) --- 2919 (void) fprintf(stderr, gettext("could not unmount zone\n")); 2920 return (Z_ERR); 2921 } 2922 2923 return ((err == Z_OK) ? Z_OK : Z_ERR); 2924} 2925 2926/* ARGSUSED */ |
3096int | 2927static int |
3097zfm_print(const char *p, void *r) { 3098 zerror(" %s\n", p); 3099 return (0); 3100} 3101 | 2928zfm_print(const char *p, void *r) { 2929 zerror(" %s\n", p); 2930 return (0); 2931} 2932 |
2933int 2934clone_copy(char *source_zonepath, char *zonepath) 2935{ 2936 int err; 2937 2938 /* Don't clone the zone if anything is still mounted there */ 2939 if (zonecfg_find_mounts(source_zonepath, NULL, NULL)) { 2940 zerror(gettext("These file systems are mounted on " 2941 "subdirectories of %s.\n"), source_zonepath); 2942 (void) zonecfg_find_mounts(source_zonepath, zfm_print, NULL); 2943 return (Z_ERR); 2944 } 2945 2946 /* 2947 * Attempt to create a ZFS fs for the zonepath. As usual, we don't 2948 * care if this works or not since we always have the default behavior 2949 * of a simple directory for the zonepath. 2950 */ 2951 create_zfs_zonepath(zonepath); 2952 2953 (void) printf(gettext("Copying %s..."), source_zonepath); 2954 (void) fflush(stdout); 2955 2956 err = copy_zone(source_zonepath, zonepath); 2957 2958 (void) printf("\n"); 2959 2960 return (err); 2961} 2962 |
|
3102static int 3103clone_func(int argc, char *argv[]) 3104{ 3105 char *source_zone = NULL; 3106 int lockfd; 3107 int err, arg; 3108 char zonepath[MAXPATHLEN]; 3109 char source_zonepath[MAXPATHLEN]; 3110 zone_state_t state; 3111 zone_entry_t *zent; | 2963static int 2964clone_func(int argc, char *argv[]) 2965{ 2966 char *source_zone = NULL; 2967 int lockfd; 2968 int err, arg; 2969 char zonepath[MAXPATHLEN]; 2970 char source_zonepath[MAXPATHLEN]; 2971 zone_state_t state; 2972 zone_entry_t *zent; |
3112 char *method = "copy"; | 2973 char *method = NULL; 2974 char *snapshot = NULL; |
3113 3114 if (zonecfg_in_alt_root()) { 3115 zerror(gettext("cannot clone zone in alternate root")); 3116 return (Z_ERR); 3117 } 3118 3119 optind = 0; | 2975 2976 if (zonecfg_in_alt_root()) { 2977 zerror(gettext("cannot clone zone in alternate root")); 2978 return (Z_ERR); 2979 } 2980 2981 optind = 0; |
3120 if ((arg = getopt(argc, argv, "?m:")) != EOF) { | 2982 if ((arg = getopt(argc, argv, "?m:s:")) != EOF) { |
3121 switch (arg) { 3122 case '?': 3123 sub_usage(SHELP_CLONE, CMD_CLONE); 3124 return (optopt == '?' ? Z_OK : Z_USAGE); 3125 case 'm': 3126 method = optarg; 3127 break; | 2983 switch (arg) { 2984 case '?': 2985 sub_usage(SHELP_CLONE, CMD_CLONE); 2986 return (optopt == '?' ? Z_OK : Z_USAGE); 2987 case 'm': 2988 method = optarg; 2989 break; |
2990 case 's': 2991 snapshot = optarg; 2992 break; |
|
3128 default: 3129 sub_usage(SHELP_CLONE, CMD_CLONE); 3130 return (Z_USAGE); 3131 } 3132 } | 2993 default: 2994 sub_usage(SHELP_CLONE, CMD_CLONE); 2995 return (Z_USAGE); 2996 } 2997 } |
3133 if (argc != (optind + 1) || strcmp(method, "copy") != 0) { | 2998 if (argc != (optind + 1) || 2999 (method != NULL && strcmp(method, "copy") != 0)) { |
3134 sub_usage(SHELP_CLONE, CMD_CLONE); 3135 return (Z_USAGE); 3136 } 3137 source_zone = argv[optind]; 3138 if (sanity_check(target_zone, CMD_CLONE, B_FALSE, B_TRUE) != Z_OK) 3139 return (Z_ERR); 3140 if (verify_details(CMD_CLONE) != Z_OK) 3141 return (Z_ERR); 3142 3143 /* 3144 * We also need to do some extra validation on the source zone. 3145 */ | 3000 sub_usage(SHELP_CLONE, CMD_CLONE); 3001 return (Z_USAGE); 3002 } 3003 source_zone = argv[optind]; 3004 if (sanity_check(target_zone, CMD_CLONE, B_FALSE, B_TRUE) != Z_OK) 3005 return (Z_ERR); 3006 if (verify_details(CMD_CLONE) != Z_OK) 3007 return (Z_ERR); 3008 3009 /* 3010 * We also need to do some extra validation on the source zone. 3011 */ |
3146 | |
3147 if (strcmp(source_zone, GLOBAL_ZONENAME) == 0) { 3148 zerror(gettext("%s operation is invalid for the global zone."), 3149 cmd_to_str(CMD_CLONE)); 3150 return (Z_ERR); 3151 } 3152 3153 if (strncmp(source_zone, "SUNW", 4) == 0) { 3154 zerror(gettext("%s operation is invalid for zones starting " --- 53 unchanged lines hidden (view full) --- 3208 3209 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3210 != Z_OK) { 3211 errno = err; 3212 zperror2(target_zone, gettext("could not get zone path")); 3213 goto done; 3214 } 3215 | 3012 if (strcmp(source_zone, GLOBAL_ZONENAME) == 0) { 3013 zerror(gettext("%s operation is invalid for the global zone."), 3014 cmd_to_str(CMD_CLONE)); 3015 return (Z_ERR); 3016 } 3017 3018 if (strncmp(source_zone, "SUNW", 4) == 0) { 3019 zerror(gettext("%s operation is invalid for zones starting " --- 53 unchanged lines hidden (view full) --- 3073 3074 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3075 != Z_OK) { 3076 errno = err; 3077 zperror2(target_zone, gettext("could not get zone path")); 3078 goto done; 3079 } 3080 |
3216 /* Don't clone the zone if anything is still mounted there */ 3217 if (zonecfg_find_mounts(source_zonepath, NULL, NULL)) { 3218 zerror(gettext("These file-systems are mounted on " 3219 "subdirectories of %s.\n"), source_zonepath); 3220 (void) zonecfg_find_mounts(source_zonepath, zfm_print, NULL); 3221 err = Z_ERR; 3222 goto done; 3223 } 3224 | |
3225 if ((err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE)) 3226 != Z_OK) { 3227 errno = err; 3228 zperror2(target_zone, gettext("could not set state")); 3229 goto done; 3230 } 3231 | 3081 if ((err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE)) 3082 != Z_OK) { 3083 errno = err; 3084 zperror2(target_zone, gettext("could not set state")); 3085 goto done; 3086 } 3087 |
3232 (void) printf(gettext("Cloning zonepath %s..."), source_zonepath); 3233 (void) fflush(stdout); | 3088 if (snapshot != NULL) { 3089 err = clone_snapshot_zfs(snapshot, zonepath); 3090 } else { 3091 /* 3092 * We always copy the clone unless the source is ZFS and a 3093 * ZFS clone worked. We fallback to copying if the ZFS clone 3094 * fails for some reason. 3095 */ 3096 err = Z_ERR; 3097 if (method == NULL && is_zonepath_zfs(source_zonepath)) 3098 err = clone_zfs(source_zone, source_zonepath, zonepath); |
3234 | 3099 |
3235 err = copy_zone(source_zonepath, zonepath); 3236 (void) printf("\n"); 3237 if (err != Z_OK) 3238 goto done; | 3100 if (err != Z_OK) 3101 err = clone_copy(source_zonepath, zonepath); 3102 } |
3239 | 3103 |
3240 err = unconfigure_zone(zonepath); | 3104 if (err == Z_OK) 3105 err = unconfigure_zone(zonepath); |
3241 3242done: 3243 release_lock_file(lockfd); 3244 return ((err == Z_OK) ? Z_OK : Z_ERR); 3245} 3246 3247#define RMCOMMAND "/usr/bin/rm -rf" 3248 3249/* | 3106 3107done: 3108 release_lock_file(lockfd); 3109 return ((err == Z_OK) ? Z_OK : Z_ERR); 3110} 3111 3112#define RMCOMMAND "/usr/bin/rm -rf" 3113 3114/* |
3250 * Used when moving a zonepath (via copying) to clean up the old path or 3251 * the new path if there was an error. | 3115 * Used when removing a zonepath after uninstalling or cleaning up after 3116 * the move subcommand. This handles a zonepath that has non-standard 3117 * contents so that we will only cleanup the stuff we know about and leave 3118 * any user data alone. |
3252 * | 3119 * |
3253 * This function handles the case of a zonepath being a zfs filesystem. 3254 * If it is a zfs filesystem, we cannot just remove the whole zonepath 3255 * since we can't remove the filesystem itself. Instead, we have to remove 3256 * the contents of the filesystem, but not the .zfs directory. | 3120 * If the "all" parameter is true then we should remove the whole zonepath 3121 * even if it has non-standard files/directories in it. This can be used when 3122 * we need to cleanup after moving the zonepath across file systems. 3123 * 3124 * We "exec" the RMCOMMAND so that the returned status is that of RMCOMMAND 3125 * and not the shell. |
3257 */ 3258static int | 3126 */ 3127static int |
3259remove_zonepath(char *zonepath) | 3128cleanup_zonepath(char *zonepath, boolean_t all) |
3260{ | 3129{ |
3261 int status; 3262 boolean_t is_zfs = B_FALSE; 3263 struct stat buf; 3264 char cmdbuf[sizeof (RMCOMMAND) + MAXPATHLEN + 128]; | 3130 int status; 3131 int i; 3132 boolean_t non_std = B_FALSE; 3133 struct dirent *dp; 3134 DIR *dirp; 3135 char *std_entries[] = {"dev", "lu", "root", NULL}; 3136 /* (MAXPATHLEN * 3) is for the 3 std_entries dirs */ 3137 char cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 3) + 64]; |
3265 | 3138 |
3266 (void) snprintf(cmdbuf, sizeof (cmdbuf), "%s/.zfs", zonepath); | 3139 /* 3140 * We shouldn't need these checks but lets be paranoid since we 3141 * could blow away the whole system here if we got the wrong zonepath. 3142 */ 3143 if (*zonepath == NULL || strcmp(zonepath, "/") == 0) { 3144 (void) fprintf(stderr, "invalid zonepath '%s'\n", zonepath); 3145 return (Z_INVAL); 3146 } |
3267 | 3147 |
3268 if (stat(cmdbuf, &buf) == 0 && S_ISDIR(buf.st_mode)) 3269 is_zfs = B_TRUE; | 3148 /* 3149 * If the dirpath is already gone (maybe it was manually removed) then 3150 * we just return Z_OK so that the cleanup is successful. 3151 */ 3152 if ((dirp = opendir(zonepath)) == NULL) 3153 return (Z_OK); |
3270 | 3154 |
3271 if (is_zfs) { | 3155 /* 3156 * Look through the zonepath directory to see if there are any 3157 * non-standard files/dirs. Also skip .zfs since that might be 3158 * there but we'll handle ZFS file systems as a special case. 3159 */ 3160 while ((dp = readdir(dirp)) != NULL) { 3161 if (strcmp(dp->d_name, ".") == 0 || 3162 strcmp(dp->d_name, "..") == 0 || 3163 strcmp(dp->d_name, ".zfs") == 0) 3164 continue; 3165 3166 for (i = 0; std_entries[i] != NULL; i++) 3167 if (strcmp(dp->d_name, std_entries[i]) == 0) 3168 break; 3169 3170 if (std_entries[i] == NULL) 3171 non_std = B_TRUE; 3172 } 3173 (void) closedir(dirp); 3174 3175 if (!all && non_std) { |
3272 /* | 3176 /* |
3273 * This doesn't handle the (unlikely) case that there are 3274 * directories or files in the top-level zonepath with white 3275 * space in the names. | 3177 * There are extra, non-standard directories/files in the 3178 * zonepath so we don't want to remove the zonepath. We 3179 * just want to remove the standard directories and leave 3180 * the user data alone. |
3276 */ | 3181 */ |
3277 (void) snprintf(cmdbuf, sizeof (cmdbuf), 3278 "cd %s && /usr/bin/ls -A | /usr/bin/egrep -v '^\\.zfs$' | " 3279 "/usr/bin/xargs " RMCOMMAND, zonepath); 3280 } else { 3281 /* 3282 * "exec" the command so that the returned status is 3283 * that of rm and not the shell. 3284 */ 3285 (void) snprintf(cmdbuf, sizeof (cmdbuf), 3286 "exec " RMCOMMAND " %s", zonepath); 3287 } | 3182 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND); |
3288 | 3183 |
3289 status = do_subproc(cmdbuf); | 3184 for (i = 0; std_entries[i] != NULL; i++) { 3185 char tmpbuf[MAXPATHLEN]; |
3290 | 3186 |
3291 return (subproc_status("rm", status)); | 3187 if (snprintf(tmpbuf, sizeof (tmpbuf), " %s/%s", 3188 zonepath, std_entries[i]) >= sizeof (tmpbuf) || 3189 strlcat(cmdbuf, tmpbuf, sizeof (cmdbuf)) >= 3190 sizeof (cmdbuf)) { 3191 (void) fprintf(stderr, 3192 gettext("path is too long\n")); 3193 return (Z_INVAL); 3194 } 3195 } |
3292 | 3196 |
3197 status = do_subproc(cmdbuf); 3198 3199 (void) fprintf(stderr, gettext("WARNING: Unable to completely " 3200 "remove %s\nbecause it contains additional user data. " 3201 "Only the standard directory\nentries have been " 3202 "removed.\n"), 3203 zonepath); 3204 3205 return (subproc_status(RMCOMMAND, status)); 3206 } 3207 3208 /* 3209 * There is nothing unexpected in the zonepath, try to get rid of the 3210 * whole zonepath directory. 3211 * 3212 * If the zonepath is its own zfs file system, try to destroy the 3213 * file system. If that fails for some reason (e.g. it has clones) 3214 * then we'll just remove the contents of the zonepath. 3215 */ 3216 if (is_zonepath_zfs(zonepath)) { 3217 if (destroy_zfs(zonepath) == Z_OK) 3218 return (Z_OK); 3219 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND 3220 " %s/*", zonepath); 3221 status = do_subproc(cmdbuf); 3222 return (subproc_status(RMCOMMAND, status)); 3223 } 3224 3225 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND " %s", 3226 zonepath); 3227 status = do_subproc(cmdbuf); 3228 return (subproc_status(RMCOMMAND, status)); |
|
3293} 3294 3295static int 3296move_func(int argc, char *argv[]) 3297{ 3298 char *new_zonepath = NULL; 3299 int lockfd; 3300 int err, arg; 3301 char zonepath[MAXPATHLEN]; 3302 zone_dochandle_t handle; 3303 boolean_t fast; | 3229} 3230 3231static int 3232move_func(int argc, char *argv[]) 3233{ 3234 char *new_zonepath = NULL; 3235 int lockfd; 3236 int err, arg; 3237 char zonepath[MAXPATHLEN]; 3238 zone_dochandle_t handle; 3239 boolean_t fast; |
3240 boolean_t is_zfs = B_FALSE; 3241 struct dirent *dp; 3242 DIR *dirp; 3243 boolean_t empty = B_TRUE; |
|
3304 boolean_t revert; 3305 struct stat zonepath_buf; 3306 struct stat new_zonepath_buf; 3307 3308 if (zonecfg_in_alt_root()) { 3309 zerror(gettext("cannot move zone in alternate root")); 3310 return (Z_ERR); 3311 } --- 17 unchanged lines hidden (view full) --- 3329 if (sanity_check(target_zone, CMD_MOVE, B_FALSE, B_TRUE) != Z_OK) 3330 return (Z_ERR); 3331 if (verify_details(CMD_MOVE) != Z_OK) 3332 return (Z_ERR); 3333 3334 /* 3335 * Check out the new zonepath. This has the side effect of creating 3336 * a directory for the new zonepath. We depend on this later when we | 3244 boolean_t revert; 3245 struct stat zonepath_buf; 3246 struct stat new_zonepath_buf; 3247 3248 if (zonecfg_in_alt_root()) { 3249 zerror(gettext("cannot move zone in alternate root")); 3250 return (Z_ERR); 3251 } --- 17 unchanged lines hidden (view full) --- 3269 if (sanity_check(target_zone, CMD_MOVE, B_FALSE, B_TRUE) != Z_OK) 3270 return (Z_ERR); 3271 if (verify_details(CMD_MOVE) != Z_OK) 3272 return (Z_ERR); 3273 3274 /* 3275 * Check out the new zonepath. This has the side effect of creating 3276 * a directory for the new zonepath. We depend on this later when we |
3337 * stat to see if we are doing a cross file-system move or not. | 3277 * stat to see if we are doing a cross file system move or not. |
3338 */ 3339 if (validate_zonepath(new_zonepath, CMD_MOVE) != Z_OK) 3340 return (Z_ERR); 3341 3342 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3343 != Z_OK) { 3344 errno = err; 3345 zperror2(target_zone, gettext("could not get zone path")); --- 5 unchanged lines hidden (view full) --- 3351 return (Z_ERR); 3352 } 3353 3354 if (stat(new_zonepath, &new_zonepath_buf) == -1) { 3355 zperror(gettext("could not stat new zone path"), B_FALSE); 3356 return (Z_ERR); 3357 } 3358 | 3278 */ 3279 if (validate_zonepath(new_zonepath, CMD_MOVE) != Z_OK) 3280 return (Z_ERR); 3281 3282 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3283 != Z_OK) { 3284 errno = err; 3285 zperror2(target_zone, gettext("could not get zone path")); --- 5 unchanged lines hidden (view full) --- 3291 return (Z_ERR); 3292 } 3293 3294 if (stat(new_zonepath, &new_zonepath_buf) == -1) { 3295 zperror(gettext("could not stat new zone path"), B_FALSE); 3296 return (Z_ERR); 3297 } 3298 |
3299 /* 3300 * Check if the destination directory is empty. 3301 */ 3302 if ((dirp = opendir(new_zonepath)) == NULL) { 3303 zperror(gettext("could not open new zone path"), B_FALSE); 3304 return (Z_ERR); 3305 } 3306 while ((dp = readdir(dirp)) != (struct dirent *)0) { 3307 if (strcmp(dp->d_name, ".") == 0 || 3308 strcmp(dp->d_name, "..") == 0) 3309 continue; 3310 empty = B_FALSE; 3311 break; 3312 } 3313 (void) closedir(dirp); 3314 3315 /* Error if there is anything in the destination directory. */ 3316 if (!empty) { 3317 (void) fprintf(stderr, gettext("could not move zone to %s: " 3318 "directory not empty\n"), new_zonepath); 3319 return (Z_ERR); 3320 } 3321 |
|
3359 /* Don't move the zone if anything is still mounted there */ 3360 if (zonecfg_find_mounts(zonepath, NULL, NULL)) { | 3322 /* Don't move the zone if anything is still mounted there */ 3323 if (zonecfg_find_mounts(zonepath, NULL, NULL)) { |
3361 zerror(gettext("These file-systems are mounted on " | 3324 zerror(gettext("These file systems are mounted on " |
3362 "subdirectories of %s.\n"), zonepath); 3363 (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); 3364 return (Z_ERR); 3365 } 3366 3367 /* | 3325 "subdirectories of %s.\n"), zonepath); 3326 (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); 3327 return (Z_ERR); 3328 } 3329 3330 /* |
3368 * Check if we are moving in the same filesystem and can do a fast 3369 * move or if we are crossing filesystems and have to copy the data. | 3331 * Check if we are moving in the same file system and can do a fast 3332 * move or if we are crossing file systems and have to copy the data. |
3370 */ 3371 fast = (zonepath_buf.st_dev == new_zonepath_buf.st_dev); 3372 3373 if ((handle = zonecfg_init_handle()) == NULL) { 3374 zperror(cmd_to_str(CMD_MOVE), B_TRUE); 3375 return (Z_ERR); 3376 } 3377 --- 7 unchanged lines hidden (view full) --- 3385 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 3386 zerror(gettext("another %s may have an operation in progress."), 3387 "zoneadm"); 3388 zonecfg_fini_handle(handle); 3389 return (Z_ERR); 3390 } 3391 3392 /* | 3333 */ 3334 fast = (zonepath_buf.st_dev == new_zonepath_buf.st_dev); 3335 3336 if ((handle = zonecfg_init_handle()) == NULL) { 3337 zperror(cmd_to_str(CMD_MOVE), B_TRUE); 3338 return (Z_ERR); 3339 } 3340 --- 7 unchanged lines hidden (view full) --- 3348 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 3349 zerror(gettext("another %s may have an operation in progress."), 3350 "zoneadm"); 3351 zonecfg_fini_handle(handle); 3352 return (Z_ERR); 3353 } 3354 3355 /* |
3393 * We're making some file-system changes now so we have to clean up 3394 * the file-system before we are done. This will either clean up the | 3356 * We're making some file system changes now so we have to clean up 3357 * the file system before we are done. This will either clean up the |
3395 * new zonepath if the zonecfg update failed or it will clean up the 3396 * old zonepath if everything is ok. 3397 */ 3398 revert = B_TRUE; 3399 | 3358 * new zonepath if the zonecfg update failed or it will clean up the 3359 * old zonepath if everything is ok. 3360 */ 3361 revert = B_TRUE; 3362 |
3400 if (fast) { 3401 /* same filesystem, use rename for a quick move */ | 3363 if (is_zonepath_zfs(zonepath) && 3364 move_zfs(zonepath, new_zonepath) != Z_ERR) { 3365 is_zfs = B_TRUE; |
3402 | 3366 |
3367 } else if (fast) { 3368 /* same file system, use rename for a quick move */ 3369 |
|
3403 /* 3404 * Remove the new_zonepath directory that got created above 3405 * during the validation. It gets in the way of the rename. 3406 */ 3407 if (rmdir(new_zonepath) != 0) { 3408 zperror(gettext("could not rmdir new zone path"), 3409 B_FALSE); 3410 zonecfg_fini_handle(handle); --- 9 unchanged lines hidden (view full) --- 3420 */ 3421 zperror(gettext("could not move zone"), B_FALSE); 3422 zonecfg_fini_handle(handle); 3423 release_lock_file(lockfd); 3424 return (Z_ERR); 3425 } 3426 3427 } else { | 3370 /* 3371 * Remove the new_zonepath directory that got created above 3372 * during the validation. It gets in the way of the rename. 3373 */ 3374 if (rmdir(new_zonepath) != 0) { 3375 zperror(gettext("could not rmdir new zone path"), 3376 B_FALSE); 3377 zonecfg_fini_handle(handle); --- 9 unchanged lines hidden (view full) --- 3387 */ 3388 zperror(gettext("could not move zone"), B_FALSE); 3389 zonecfg_fini_handle(handle); 3390 release_lock_file(lockfd); 3391 return (Z_ERR); 3392 } 3393 3394 } else { |
3395 /* 3396 * Attempt to create a ZFS fs for the new zonepath. As usual, 3397 * we don't care if this works or not since we always have the 3398 * default behavior of a simple directory for the zonepath. 3399 */ 3400 create_zfs_zonepath(new_zonepath); 3401 |
|
3428 (void) printf(gettext( | 3402 (void) printf(gettext( |
3429 "Moving across file-systems; copying zonepath %s..."), | 3403 "Moving across file systems; copying zonepath %s..."), |
3430 zonepath); 3431 (void) fflush(stdout); 3432 3433 err = copy_zone(zonepath, new_zonepath); 3434 3435 (void) printf("\n"); 3436 if (err != Z_OK) 3437 goto done; --- 13 unchanged lines hidden (view full) --- 3451 3452 revert = B_FALSE; 3453 3454done: 3455 zonecfg_fini_handle(handle); 3456 release_lock_file(lockfd); 3457 3458 /* | 3404 zonepath); 3405 (void) fflush(stdout); 3406 3407 err = copy_zone(zonepath, new_zonepath); 3408 3409 (void) printf("\n"); 3410 if (err != Z_OK) 3411 goto done; --- 13 unchanged lines hidden (view full) --- 3425 3426 revert = B_FALSE; 3427 3428done: 3429 zonecfg_fini_handle(handle); 3430 release_lock_file(lockfd); 3431 3432 /* |
3459 * Clean up the file-system based on how things went. We either | 3433 * Clean up the file system based on how things went. We either |
3460 * clean up the new zonepath if the operation failed for some reason 3461 * or we clean up the old zonepath if everything is ok. 3462 */ 3463 if (revert) { 3464 /* The zonecfg update failed, cleanup the new zonepath. */ | 3434 * clean up the new zonepath if the operation failed for some reason 3435 * or we clean up the old zonepath if everything is ok. 3436 */ 3437 if (revert) { 3438 /* The zonecfg update failed, cleanup the new zonepath. */ |
3465 if (fast) { | 3439 if (is_zfs) { 3440 if (move_zfs(new_zonepath, zonepath) == Z_ERR) { 3441 (void) fprintf(stderr, gettext("could not " 3442 "restore zonepath, the zfs mountpoint is " 3443 "set as:\n%s\n"), new_zonepath); 3444 /* 3445 * err is already != Z_OK since we're reverting 3446 */ 3447 } 3448 3449 } else if (fast) { |
3466 if (rename(new_zonepath, zonepath) != 0) { 3467 zperror(gettext("could not restore zonepath"), 3468 B_FALSE); 3469 /* 3470 * err is already != Z_OK since we're reverting 3471 */ 3472 } 3473 } else { 3474 (void) printf(gettext("Cleaning up zonepath %s..."), 3475 new_zonepath); 3476 (void) fflush(stdout); | 3450 if (rename(new_zonepath, zonepath) != 0) { 3451 zperror(gettext("could not restore zonepath"), 3452 B_FALSE); 3453 /* 3454 * err is already != Z_OK since we're reverting 3455 */ 3456 } 3457 } else { 3458 (void) printf(gettext("Cleaning up zonepath %s..."), 3459 new_zonepath); 3460 (void) fflush(stdout); |
3477 err = remove_zonepath(new_zonepath); | 3461 err = cleanup_zonepath(new_zonepath, B_TRUE); |
3478 (void) printf("\n"); 3479 3480 if (err != Z_OK) { 3481 errno = err; 3482 zperror(gettext("could not remove new " 3483 "zonepath"), B_TRUE); 3484 } else { 3485 /* 3486 * Because we're reverting we know the mainline 3487 * code failed but we just reused the err 3488 * variable so we reset it back to Z_ERR. 3489 */ 3490 err = Z_ERR; 3491 } 3492 } 3493 3494 } else { 3495 /* The move was successful, cleanup the old zonepath. */ | 3462 (void) printf("\n"); 3463 3464 if (err != Z_OK) { 3465 errno = err; 3466 zperror(gettext("could not remove new " 3467 "zonepath"), B_TRUE); 3468 } else { 3469 /* 3470 * Because we're reverting we know the mainline 3471 * code failed but we just reused the err 3472 * variable so we reset it back to Z_ERR. 3473 */ 3474 err = Z_ERR; 3475 } 3476 } 3477 3478 } else { 3479 /* The move was successful, cleanup the old zonepath. */ |
3496 if (!fast) { | 3480 if (!is_zfs && !fast) { |
3497 (void) printf( 3498 gettext("Cleaning up zonepath %s..."), zonepath); 3499 (void) fflush(stdout); | 3481 (void) printf( 3482 gettext("Cleaning up zonepath %s..."), zonepath); 3483 (void) fflush(stdout); |
3500 err = remove_zonepath(zonepath); | 3484 err = cleanup_zonepath(zonepath, B_TRUE); |
3501 (void) printf("\n"); 3502 3503 if (err != Z_OK) { 3504 errno = err; 3505 zperror(gettext("could not remove zonepath"), 3506 B_TRUE); 3507 } 3508 } --- 35 unchanged lines hidden (view full) --- 3544 != Z_OK) { 3545 errno = err; 3546 zperror2(target_zone, gettext("could not get zone path")); 3547 return (Z_ERR); 3548 } 3549 3550 /* Don't detach the zone if anything is still mounted there */ 3551 if (zonecfg_find_mounts(zonepath, NULL, NULL)) { | 3485 (void) printf("\n"); 3486 3487 if (err != Z_OK) { 3488 errno = err; 3489 zperror(gettext("could not remove zonepath"), 3490 B_TRUE); 3491 } 3492 } --- 35 unchanged lines hidden (view full) --- 3528 != Z_OK) { 3529 errno = err; 3530 zperror2(target_zone, gettext("could not get zone path")); 3531 return (Z_ERR); 3532 } 3533 3534 /* Don't detach the zone if anything is still mounted there */ 3535 if (zonecfg_find_mounts(zonepath, NULL, NULL)) { |
3552 zerror(gettext("These file-systems are mounted on " | 3536 zerror(gettext("These file systems are mounted on " |
3553 "subdirectories of %s.\n"), zonepath); 3554 (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); 3555 return (Z_ERR); 3556 } 3557 3558 if ((handle = zonecfg_init_handle()) == NULL) { 3559 zperror(cmd_to_str(CMD_DETACH), B_TRUE); 3560 return (Z_ERR); --- 35 unchanged lines hidden (view full) --- 3596done: 3597 zonecfg_fini_handle(handle); 3598 release_lock_file(lockfd); 3599 3600 return ((err == Z_OK) ? Z_OK : Z_ERR); 3601} 3602 3603/* | 3537 "subdirectories of %s.\n"), zonepath); 3538 (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); 3539 return (Z_ERR); 3540 } 3541 3542 if ((handle = zonecfg_init_handle()) == NULL) { 3543 zperror(cmd_to_str(CMD_DETACH), B_TRUE); 3544 return (Z_ERR); --- 35 unchanged lines hidden (view full) --- 3580done: 3581 zonecfg_fini_handle(handle); 3582 release_lock_file(lockfd); 3583 3584 return ((err == Z_OK) ? Z_OK : Z_ERR); 3585} 3586 3587/* |
3604 * Find the specified package in the sw inventory on the handle and check 3605 * if the version matches what is passed in. 3606 * Return 0 if the packages match 3607 * 1 if the package is found but we have a version mismatch 3608 * -1 if the package is not found 3609 */ 3610static int 3611pkg_cmp(zone_dochandle_t handle, char *pkg_name, char *pkg_vers, 3612 char *return_vers, int vers_size) 3613{ 3614 int res = -1; 3615 struct zone_pkgtab pkgtab; 3616 3617 if (zonecfg_setpkgent(handle) != Z_OK) { 3618 (void) fprintf(stderr, 3619 gettext("unable to enumerate packages\n")); 3620 return (Z_ERR); 3621 } 3622 3623 while (zonecfg_getpkgent(handle, &pkgtab) == Z_OK) { 3624 if (strcmp(pkg_name, pkgtab.zone_pkg_name) != 0) 3625 continue; 3626 3627 if (strcmp(pkg_vers, pkgtab.zone_pkg_version) == 0) { 3628 res = 0; 3629 break; 3630 } 3631 3632 (void) strlcpy(return_vers, pkgtab.zone_pkg_version, vers_size); 3633 res = 1; 3634 break; 3635 } 3636 3637 (void) zonecfg_endpkgent(handle); 3638 return (res); 3639} 3640 3641/* 3642 * Used in software comparisons to check the packages between the two zone 3643 * handles. The packages have to match or we print a message telling the 3644 * user what is out of sync. The src_cmp flag tells us if the first handle 3645 * is the source machine global zone or not. This is used to enable the 3646 * right messages to be printed and also to enable extra version checking 3647 * that is not needed for the opposite comparison. 3648 */ 3649static int 3650pkg_check(char *header, zone_dochandle_t handle1, zone_dochandle_t handle2, 3651 boolean_t src_cmp) 3652{ 3653 int err; 3654 int res = Z_OK; 3655 boolean_t do_header = B_TRUE; 3656 char other_vers[ZONE_PKG_VERSMAX]; 3657 struct zone_pkgtab pkgtab; 3658 3659 if (zonecfg_setpkgent(handle1) != Z_OK) { 3660 (void) fprintf(stderr, 3661 gettext("unable to enumerate packages\n")); 3662 return (Z_ERR); 3663 } 3664 3665 while (zonecfg_getpkgent(handle1, &pkgtab) == Z_OK) { 3666 if ((err = pkg_cmp(handle2, pkgtab.zone_pkg_name, 3667 pkgtab.zone_pkg_version, other_vers, sizeof (other_vers))) 3668 != 0) { 3669 if (do_header && (err < 0 || src_cmp)) { 3670 /* LINTED E_SEC_PRINTF_VAR_FMT */ 3671 (void) fprintf(stderr, header); 3672 do_header = B_FALSE; 3673 } 3674 if (err < 0) { 3675 (void) fprintf(stderr, 3676 (src_cmp == B_TRUE) ? 3677 gettext("\t%s: not installed\n\t\t(%s)\n") : 3678 gettext("\t%s (%s)\n"), 3679 pkgtab.zone_pkg_name, 3680 pkgtab.zone_pkg_version); 3681 res = Z_ERR; 3682 } else if (src_cmp) { 3683 (void) fprintf(stderr, gettext( 3684 "\t%s: version mismatch\n\t\t(%s)" 3685 "\n\t\t(%s)\n"), 3686 pkgtab.zone_pkg_name, 3687 pkgtab.zone_pkg_version, other_vers); 3688 res = Z_ERR; 3689 } 3690 } 3691 } 3692 3693 (void) zonecfg_endpkgent(handle1); 3694 3695 return (res); 3696} 3697 3698/* 3699 * Find the specified patch in the sw inventory on the handle and check 3700 * if the version matches what is passed in. 3701 * Return 0 if the patches match 3702 * 1 if the patches is found but we have a version mismatch 3703 * -1 if the patches is not found 3704 */ 3705static int 3706patch_cmp(zone_dochandle_t handle, char *patch_id, char *patch_vers, 3707 char *return_vers, int vers_size) 3708{ 3709 int res = -1; 3710 struct zone_patchtab patchtab; 3711 3712 if (zonecfg_setpatchent(handle) != Z_OK) { 3713 (void) fprintf(stderr, 3714 gettext("unable to enumerate patches\n")); 3715 return (Z_ERR); 3716 } 3717 3718 while (zonecfg_getpatchent(handle, &patchtab) == Z_OK) { 3719 char *p; 3720 3721 if ((p = strchr(patchtab.zone_patch_id, '-')) != NULL) 3722 *p++ = '\0'; 3723 else 3724 p = ""; 3725 3726 if (strcmp(patch_id, patchtab.zone_patch_id) != 0) 3727 continue; 3728 3729 if (strcmp(patch_vers, p) == 0) { 3730 res = 0; 3731 break; 3732 } 3733 3734 (void) strlcpy(return_vers, p, vers_size); 3735 /* 3736 * Keep checking. This handles the case where multiple 3737 * versions of the same patch is installed. 3738 */ 3739 res = 1; 3740 } 3741 3742 (void) zonecfg_endpatchent(handle); 3743 return (res); 3744} 3745 3746/* 3747 * Used in software comparisons to check the patches between the two zone 3748 * handles. The patches have to match or we print a message telling the 3749 * user what is out of sync. The src_cmp flag tells us if the first handle 3750 * is the source machine global zone or not. This is used to enable the 3751 * right messages to be printed and also to enable extra version checking 3752 * that is not needed for the opposite comparison. 3753 */ 3754static int 3755patch_check(char *header, zone_dochandle_t handle1, zone_dochandle_t handle2, 3756 boolean_t src_cmp) 3757{ 3758 int err; 3759 int res = Z_OK; 3760 boolean_t do_header = B_TRUE; 3761 char other_vers[MAXNAMELEN]; 3762 struct zone_patchtab patchtab; 3763 3764 if (zonecfg_setpatchent(handle1) != Z_OK) { 3765 (void) fprintf(stderr, 3766 gettext("unable to enumerate patches\n")); 3767 return (Z_ERR); 3768 } 3769 3770 while (zonecfg_getpatchent(handle1, &patchtab) == Z_OK) { 3771 char *patch_vers; 3772 3773 if ((patch_vers = strchr(patchtab.zone_patch_id, '-')) != NULL) 3774 *patch_vers++ = '\0'; 3775 else 3776 patch_vers = ""; 3777 3778 if ((err = patch_cmp(handle2, patchtab.zone_patch_id, 3779 patch_vers, other_vers, sizeof (other_vers))) != 0) { 3780 if (do_header && (err < 0 || src_cmp)) { 3781 /* LINTED E_SEC_PRINTF_VAR_FMT */ 3782 (void) fprintf(stderr, header); 3783 do_header = B_FALSE; 3784 } 3785 if (err < 0) { 3786 (void) fprintf(stderr, 3787 (src_cmp == B_TRUE) ? 3788 gettext("\t%s: not installed\n") : 3789 gettext("\t%s\n"), 3790 patchtab.zone_patch_id); 3791 res = Z_ERR; 3792 } else if (src_cmp) { 3793 (void) fprintf(stderr, 3794 gettext("\t%s: version mismatch\n\t\t(%s) " 3795 "(%s)\n"), patchtab.zone_patch_id, 3796 patch_vers, other_vers); 3797 res = Z_ERR; 3798 } 3799 } 3800 } 3801 3802 (void) zonecfg_endpatchent(handle1); 3803 3804 return (res); 3805} 3806 3807/* 3808 * Compare the software on the local global zone and source system global 3809 * zone. Used when we are trying to attach a zone during migration. 3810 * l_handle is for the local system and s_handle is for the source system. 3811 * These have a snapshot of the appropriate packages and patches in the global 3812 * zone for the two machines. 3813 * The functions called here will print any messages that are needed to 3814 * inform the user about package or patch problems. 3815 */ 3816static int 3817sw_cmp(zone_dochandle_t l_handle, zone_dochandle_t s_handle) 3818{ 3819 char *hdr; 3820 int res = Z_OK; 3821 3822 /* 3823 * Check the source host for pkgs (and versions) that are not on the 3824 * local host. 3825 */ 3826 hdr = gettext("These packages installed on the source system are " 3827 "inconsistent with this system:\n"); 3828 if (pkg_check(hdr, s_handle, l_handle, B_TRUE) != Z_OK) 3829 res = Z_ERR; 3830 3831 /* 3832 * Now check the local host for pkgs that were not on the source host. 3833 * We already handled version mismatches in the loop above. 3834 */ 3835 hdr = gettext("These packages installed on this system were " 3836 "not installed on the source system:\n"); 3837 if (pkg_check(hdr, l_handle, s_handle, B_FALSE) != Z_OK) 3838 res = Z_ERR; 3839 3840 /* 3841 * Check the source host for patches that are not on the local host. 3842 */ 3843 hdr = gettext("These patches installed on the source system are " 3844 "inconsistent with this system:\n"); 3845 if (patch_check(hdr, s_handle, l_handle, B_TRUE) != Z_OK) 3846 res = Z_ERR; 3847 3848 /* 3849 * Check the local host for patches that were not on the source host. 3850 * We already handled version mismatches in the loop above. 3851 */ 3852 hdr = gettext("These patches installed on this system were " 3853 "not installed on the source system:\n"); 3854 if (patch_check(hdr, l_handle, s_handle, B_FALSE) != Z_OK) 3855 res = Z_ERR; 3856 3857 return (res); 3858} 3859 3860/* | |
3861 * During attach we go through and fix up the /dev entries for the zone 3862 * we are attaching. In order to regenerate /dev with the correct devices, 3863 * the old /dev will be removed, the zone readied (which generates a new 3864 * /dev) then halted, then we use the info from the manifest to update 3865 * the modes, owners, etc. on the new /dev. 3866 */ 3867static int 3868dev_fix(zone_dochandle_t handle) --- 156 unchanged lines hidden (view full) --- 4025 if ((err = zonecfg_get_detach_info(handle, B_FALSE)) != Z_OK) { 4026 errno = err; 4027 zperror(gettext("getting the attach information failed"), 4028 B_TRUE); 4029 goto done; 4030 } 4031 4032 /* sw_cmp prints error msgs as necessary */ | 3588 * During attach we go through and fix up the /dev entries for the zone 3589 * we are attaching. In order to regenerate /dev with the correct devices, 3590 * the old /dev will be removed, the zone readied (which generates a new 3591 * /dev) then halted, then we use the info from the manifest to update 3592 * the modes, owners, etc. on the new /dev. 3593 */ 3594static int 3595dev_fix(zone_dochandle_t handle) --- 156 unchanged lines hidden (view full) --- 3752 if ((err = zonecfg_get_detach_info(handle, B_FALSE)) != Z_OK) { 3753 errno = err; 3754 zperror(gettext("getting the attach information failed"), 3755 B_TRUE); 3756 goto done; 3757 } 3758 3759 /* sw_cmp prints error msgs as necessary */ |
4033 if ((err = sw_cmp(handle, athandle)) != Z_OK) | 3760 if ((err = sw_cmp(handle, athandle, SW_CMP_NONE)) != Z_OK) |
4034 goto done; 4035 4036 if ((err = dev_fix(athandle)) != Z_OK) 4037 goto done; 4038 4039forced: 4040 4041 zonecfg_rm_detached(handle, force); --- 35 unchanged lines hidden (view full) --- 4077 if (tolower(line[0]) == 'n') 4078 return (0); 4079 } 4080} 4081 4082static int 4083uninstall_func(int argc, char *argv[]) 4084{ | 3761 goto done; 3762 3763 if ((err = dev_fix(athandle)) != Z_OK) 3764 goto done; 3765 3766forced: 3767 3768 zonecfg_rm_detached(handle, force); --- 35 unchanged lines hidden (view full) --- 3804 if (tolower(line[0]) == 'n') 3805 return (0); 3806 } 3807} 3808 3809static int 3810uninstall_func(int argc, char *argv[]) 3811{ |
4085 /* 6: "exec " and " " */ 4086 char cmdbuf[sizeof (RMCOMMAND) + MAXPATHLEN + 6]; | |
4087 char line[ZONENAME_MAX + 128]; /* Enough for "Are you sure ..." */ | 3812 char line[ZONENAME_MAX + 128]; /* Enough for "Are you sure ..." */ |
4088 char rootpath[MAXPATHLEN], devpath[MAXPATHLEN]; | 3813 char rootpath[MAXPATHLEN], zonepath[MAXPATHLEN]; |
4089 boolean_t force = B_FALSE; 4090 int lockfd, answer; 4091 int err, arg; | 3814 boolean_t force = B_FALSE; 3815 int lockfd, answer; 3816 int err, arg; |
4092 int status; | |
4093 4094 if (zonecfg_in_alt_root()) { 4095 zerror(gettext("cannot uninstall zone in alternate root")); 4096 return (Z_ERR); 4097 } 4098 4099 optind = 0; 4100 while ((arg = getopt(argc, argv, "?F")) != EOF) { --- 26 unchanged lines hidden (view full) --- 4127 } else if (answer == -1) { 4128 zerror(gettext("Input not from terminal and -F " 4129 "not specified: %s not done."), 4130 cmd_to_str(CMD_UNINSTALL)); 4131 return (Z_ERR); 4132 } 4133 } 4134 | 3817 3818 if (zonecfg_in_alt_root()) { 3819 zerror(gettext("cannot uninstall zone in alternate root")); 3820 return (Z_ERR); 3821 } 3822 3823 optind = 0; 3824 while ((arg = getopt(argc, argv, "?F")) != EOF) { --- 26 unchanged lines hidden (view full) --- 3851 } else if (answer == -1) { 3852 zerror(gettext("Input not from terminal and -F " 3853 "not specified: %s not done."), 3854 cmd_to_str(CMD_UNINSTALL)); 3855 return (Z_ERR); 3856 } 3857 } 3858 |
4135 if ((err = zone_get_zonepath(target_zone, devpath, 4136 sizeof (devpath))) != Z_OK) { | 3859 if ((err = zone_get_zonepath(target_zone, zonepath, 3860 sizeof (zonepath))) != Z_OK) { |
4137 errno = err; 4138 zperror2(target_zone, gettext("could not get zone path")); 4139 return (Z_ERR); 4140 } | 3861 errno = err; 3862 zperror2(target_zone, gettext("could not get zone path")); 3863 return (Z_ERR); 3864 } |
4141 (void) strlcat(devpath, "/dev", sizeof (devpath)); | |
4142 if ((err = zone_get_rootpath(target_zone, rootpath, 4143 sizeof (rootpath))) != Z_OK) { 4144 errno = err; 4145 zperror2(target_zone, gettext("could not get root path")); 4146 return (Z_ERR); 4147 } 4148 4149 /* --- 12 unchanged lines hidden (view full) --- 4162 zerror(gettext("another %s may have an operation in progress."), 4163 "zoneadm"); 4164 return (Z_ERR); 4165 } 4166 4167 /* Don't uninstall the zone if anything is mounted there */ 4168 err = zonecfg_find_mounts(rootpath, NULL, NULL); 4169 if (err) { | 3865 if ((err = zone_get_rootpath(target_zone, rootpath, 3866 sizeof (rootpath))) != Z_OK) { 3867 errno = err; 3868 zperror2(target_zone, gettext("could not get root path")); 3869 return (Z_ERR); 3870 } 3871 3872 /* --- 12 unchanged lines hidden (view full) --- 3885 zerror(gettext("another %s may have an operation in progress."), 3886 "zoneadm"); 3887 return (Z_ERR); 3888 } 3889 3890 /* Don't uninstall the zone if anything is mounted there */ 3891 err = zonecfg_find_mounts(rootpath, NULL, NULL); 3892 if (err) { |
4170 zerror(gettext("These file-systems are mounted on " | 3893 zerror(gettext("These file systems are mounted on " |
4171 "subdirectories of %s.\n"), rootpath); 4172 (void) zonecfg_find_mounts(rootpath, zfm_print, NULL); 4173 return (Z_ERR); 4174 } 4175 4176 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 4177 if (err != Z_OK) { 4178 errno = err; 4179 zperror2(target_zone, gettext("could not set state")); 4180 goto bad; 4181 } 4182 | 3894 "subdirectories of %s.\n"), rootpath); 3895 (void) zonecfg_find_mounts(rootpath, zfm_print, NULL); 3896 return (Z_ERR); 3897 } 3898 3899 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 3900 if (err != Z_OK) { 3901 errno = err; 3902 zperror2(target_zone, gettext("could not set state")); 3903 goto bad; 3904 } 3905 |
4183 /* 4184 * "exec" the command so that the returned status is that of 4185 * RMCOMMAND and not the shell. 4186 */ 4187 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND " %s", 4188 devpath); 4189 status = do_subproc(cmdbuf); 4190 if ((err = subproc_status(RMCOMMAND, status)) != Z_OK) | 3906 if ((err = cleanup_zonepath(zonepath, B_FALSE)) != Z_OK) { 3907 errno = err; 3908 zperror2(target_zone, gettext("cleaning up zonepath failed")); |
4191 goto bad; | 3909 goto bad; |
4192 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND " %s", 4193 rootpath); 4194 status = do_subproc(cmdbuf); 4195 if ((err = subproc_status(RMCOMMAND, status)) != Z_OK) 4196 goto bad; | 3910 } 3911 |
4197 err = zone_set_state(target_zone, ZONE_STATE_CONFIGURED); 4198 if (err != Z_OK) { 4199 errno = err; 4200 zperror2(target_zone, gettext("could not reset state")); 4201 } 4202bad: 4203 release_lock_file(lockfd); 4204 return (err); --- 177 unchanged lines hidden --- | 3912 err = zone_set_state(target_zone, ZONE_STATE_CONFIGURED); 3913 if (err != Z_OK) { 3914 errno = err; 3915 zperror2(target_zone, gettext("could not reset state")); 3916 } 3917bad: 3918 release_lock_file(lockfd); 3919 return (err); --- 177 unchanged lines hidden --- |