zoneadm.c (4785:9606b9fd0ed6) | zoneadm.c (5829:20241b1ccadc) |
---|---|
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 --- 6 unchanged lines hidden (view full) --- 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* | 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 --- 6 unchanged lines hidden (view full) --- 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* |
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29/* 30 * zoneadm is a command interpreter for zone administration. It is all in 31 * C (i.e., no lex/yacc), and all the argument passing is argc/argv based. --- 102 unchanged lines hidden (view full) --- 134#define SHELP_REBOOT "reboot [-- boot_arguments]" 135#define SHELP_LIST "list [-cipv]" 136#define SHELP_VERIFY "verify" 137#define SHELP_INSTALL "install [-x nodataset] [brand-specific args]" 138#define SHELP_UNINSTALL "uninstall [-F]" 139#define SHELP_CLONE "clone [-m method] [-s <ZFS snapshot>] zonename" 140#define SHELP_MOVE "move zonepath" 141#define SHELP_DETACH "detach [-n]" | 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29/* 30 * zoneadm is a command interpreter for zone administration. It is all in 31 * C (i.e., no lex/yacc), and all the argument passing is argc/argv based. --- 102 unchanged lines hidden (view full) --- 134#define SHELP_REBOOT "reboot [-- boot_arguments]" 135#define SHELP_LIST "list [-cipv]" 136#define SHELP_VERIFY "verify" 137#define SHELP_INSTALL "install [-x nodataset] [brand-specific args]" 138#define SHELP_UNINSTALL "uninstall [-F]" 139#define SHELP_CLONE "clone [-m method] [-s <ZFS snapshot>] zonename" 140#define SHELP_MOVE "move zonepath" 141#define SHELP_DETACH "detach [-n]" |
142#define SHELP_ATTACH "attach [-F] [-n | 142#define SHELP_ATTACH "attach [-F] [-n <path>] [-u]" |
143#define SHELP_MARK "mark incomplete" 144 145#define EXEC_PREFIX "exec " 146#define EXEC_LEN (strlen(EXEC_PREFIX)) 147#define RMCOMMAND "/usr/bin/rm -rf" 148 149static int cleanup_zonepath(char *, boolean_t); 150 --- 50 unchanged lines hidden (view full) --- 201static char *execname; 202static char target_brand[MAXNAMELEN]; 203static char *locale; 204char *target_zone; 205static char *target_uuid; 206 207/* used in do_subproc() and signal handler */ 208static volatile boolean_t child_killed; | 143#define SHELP_MARK "mark incomplete" 144 145#define EXEC_PREFIX "exec " 146#define EXEC_LEN (strlen(EXEC_PREFIX)) 147#define RMCOMMAND "/usr/bin/rm -rf" 148 149static int cleanup_zonepath(char *, boolean_t); 150 --- 50 unchanged lines hidden (view full) --- 201static char *execname; 202static char target_brand[MAXNAMELEN]; 203static char *locale; 204char *target_zone; 205static char *target_uuid; 206 207/* used in do_subproc() and signal handler */ 208static volatile boolean_t child_killed; |
209/* used in attach_func() and signal handler */ 210static volatile boolean_t attach_interupted; |
|
209static int do_subproc_cnt = 0; 210 211/* 212 * Used to indicate whether this zoneadm instance has another zoneadm 213 * instance in its ancestry. 214 */ 215static boolean_t zoneadm_is_nested = B_FALSE; 216 --- 83 unchanged lines hidden (view full) --- 300 "needed to attach\n\tthe zone is sent to standard output " 301 "but the zone is not actually\n\tdetached.")); 302 case CMD_ATTACH: 303 return (gettext("Attach the zone to the system. The zone " 304 "state must be 'configured'\n\tprior to attach; upon " 305 "successful completion, the zone state will be\n\t" 306 "'installed'. The system software on the current " 307 "system must be\n\tcompatible with the software on the " | 211static int do_subproc_cnt = 0; 212 213/* 214 * Used to indicate whether this zoneadm instance has another zoneadm 215 * instance in its ancestry. 216 */ 217static boolean_t zoneadm_is_nested = B_FALSE; 218 --- 83 unchanged lines hidden (view full) --- 302 "needed to attach\n\tthe zone is sent to standard output " 303 "but the zone is not actually\n\tdetached.")); 304 case CMD_ATTACH: 305 return (gettext("Attach the zone to the system. The zone " 306 "state must be 'configured'\n\tprior to attach; upon " 307 "successful completion, the zone state will be\n\t" 308 "'installed'. The system software on the current " 309 "system must be\n\tcompatible with the software on the " |
308 "zone's original system.\n\tSpecify -F to force the attach " 309 "and skip software compatibility tests.\n\tThe -n option " 310 "can be used to specify 'no-execute' mode. When -n is\n\t" 311 "used, the information needed to attach the zone is read " 312 "from the\n\tspecified path and the configuration is only " 313 "validated. The path can\n\tbe '-' to specify standard " 314 "input.")); | 310 "zone's original system or use\n\tthe -u option to update " 311 "the zone to the current system software.\n\tSpecify -F " 312 "to force the attach and skip software compatibility " 313 "tests.\n\tThe -n option can be used to specify " 314 "'no-execute' mode. When -n is\n\tused, the information " 315 "needed to attach the zone is read from the\n\tspecified " 316 "path and the configuration is only validated. The path " 317 "can\n\tbe '-' to specify standard input. The -F, -n and " 318 "-u options are\n\tmutually exclusive.")); |
315 case CMD_MARK: 316 return (gettext("Set the state of the zone. This can be used " 317 "to force the zone\n\tstate to 'incomplete' " 318 "administratively if some activity has rendered\n\tthe " 319 "zone permanently unusable. The only valid state that " 320 "may be\n\tspecified is 'incomplete'.")); 321 default: 322 return (""); --- 4554 unchanged lines hidden (view full) --- 4877cleanup: 4878 /* Cleanup from the previous actions. */ 4879 if (mounted) { 4880 if (snprintf(cmdbuf, sizeof (cmdbuf), 4881 "/usr/sbin/zlogin -S %s '/usr/bin/rm -f /etc/zones/%s.xml'", 4882 target_zone, target_zone) >= sizeof (cmdbuf)) { 4883 res = B_FALSE; 4884 } else { | 319 case CMD_MARK: 320 return (gettext("Set the state of the zone. This can be used " 321 "to force the zone\n\tstate to 'incomplete' " 322 "administratively if some activity has rendered\n\tthe " 323 "zone permanently unusable. The only valid state that " 324 "may be\n\tspecified is 'incomplete'.")); 325 default: 326 return (""); --- 4554 unchanged lines hidden (view full) --- 4881cleanup: 4882 /* Cleanup from the previous actions. */ 4883 if (mounted) { 4884 if (snprintf(cmdbuf, sizeof (cmdbuf), 4885 "/usr/sbin/zlogin -S %s '/usr/bin/rm -f /etc/zones/%s.xml'", 4886 target_zone, target_zone) >= sizeof (cmdbuf)) { 4887 res = B_FALSE; 4888 } else { |
4885 status = do_subproc(cmdbuf); | 4889 status = do_subproc_interactive(cmdbuf); |
4886 if (subproc_status("rm", status, B_TRUE) 4887 != ZONE_SUBPROC_OK) 4888 res = B_FALSE; 4889 } 4890 4891 if (unmount_func(0, NULL) != Z_OK) 4892 res = B_FALSE; 4893 } 4894 4895 if (zone_set_state(target_zone, ZONE_STATE_CONFIGURED) != Z_OK) 4896 res = B_FALSE; 4897 4898 return (res); 4899} 4900 | 4890 if (subproc_status("rm", status, B_TRUE) 4891 != ZONE_SUBPROC_OK) 4892 res = B_FALSE; 4893 } 4894 4895 if (unmount_func(0, NULL) != Z_OK) 4896 res = B_FALSE; 4897 } 4898 4899 if (zone_set_state(target_zone, ZONE_STATE_CONFIGURED) != Z_OK) 4900 res = B_FALSE; 4901 4902 return (res); 4903} 4904 |
4905/* 4906 * The zone needs to be updated so set it up for the update and initiate the 4907 * update within the scratch zone. First set the state to incomplete so we can 4908 * force-mount the zone for the update operation. We pass the -U option to the 4909 * mount so that the scratch zone is mounted without the zone's /etc and /var 4910 * being lofs mounted back into the scratch zone root. This is done by 4911 * overloading the bootbuf string in the zone_cmd_arg_t to pass -U as an option 4912 * to the mount cmd. 4913 */ |
|
4901static int | 4914static int |
4915attach_update(zone_dochandle_t handle, char *zonepath) 4916{ 4917 int err; 4918 int update_res; 4919 int status; 4920 zone_cmd_arg_t zarg; 4921 FILE *fp; 4922 struct zone_fstab fstab; 4923 char cmdbuf[(4 * MAXPATHLEN) + 20]; 4924 4925 if ((err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE)) 4926 != Z_OK) { 4927 errno = err; 4928 zperror(gettext("could not set state"), B_TRUE); 4929 return (Z_ERR); 4930 } 4931 4932 zarg.cmd = Z_FORCEMOUNT; 4933 (void) strlcpy(zarg.bootbuf, "-U", sizeof (zarg.bootbuf)); 4934 if (call_zoneadmd(target_zone, &zarg) != 0) { 4935 zerror(gettext("could not mount zone")); 4936 4937 /* We reset the state since the zone wasn't modified yet. */ 4938 if ((err = zone_set_state(target_zone, ZONE_STATE_CONFIGURED)) 4939 != Z_OK) { 4940 errno = err; 4941 zperror(gettext("could not reset state"), B_TRUE); 4942 } 4943 return (Z_ERR); 4944 } 4945 4946 /* 4947 * Move data files generated by sw_up_to_date() into the scratch 4948 * zone's /tmp. 4949 */ 4950 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec /usr/bin/mv " 4951 "%s/pkg_add %s/pkg_rm %s/lu/tmp", 4952 zonepath, zonepath, zonepath); 4953 4954 status = do_subproc_interactive(cmdbuf); 4955 if (subproc_status("mv", status, B_TRUE) != ZONE_SUBPROC_OK) { 4956 zperror(gettext("could not mv data files"), B_FALSE); 4957 goto fail; 4958 } 4959 4960 /* 4961 * Save list of inherit-pkg-dirs into zone. Since the file is in 4962 * /tmp we don't have to worry about deleting it. 4963 */ 4964 (void) snprintf(cmdbuf, sizeof (cmdbuf), "%s/lu/tmp/inherited", 4965 zonepath); 4966 if ((fp = fopen(cmdbuf, "w")) == NULL) { 4967 zperror(gettext("could not save inherit-pkg-dirs"), B_FALSE); 4968 goto fail; 4969 } 4970 if (zonecfg_setipdent(handle) != Z_OK) { 4971 zperror(gettext("could not enumerate inherit-pkg-dirs"), 4972 B_TRUE); 4973 goto fail; 4974 } 4975 while (zonecfg_getipdent(handle, &fstab) == Z_OK) { 4976 if (fprintf(fp, "%s\n", fstab.zone_fs_dir) < 0) { 4977 zperror(gettext("could not save inherit-pkg-dirs"), 4978 B_FALSE); 4979 (void) fclose(fp); 4980 goto fail; 4981 } 4982 } 4983 (void) zonecfg_endipdent(handle); 4984 if (fclose(fp) != 0) { 4985 zperror(gettext("could not save inherit-pkg-dirs"), B_FALSE); 4986 goto fail; 4987 } 4988 4989 /* run the updater inside the scratch zone */ 4990 (void) snprintf(cmdbuf, sizeof (cmdbuf), 4991 "exec /usr/sbin/zlogin -S %s " 4992 "/usr/lib/brand/native/attach_update %s", target_zone, target_zone); 4993 4994 update_res = Z_OK; 4995 status = do_subproc_interactive(cmdbuf); 4996 if (subproc_status("attach_update", status, B_TRUE) 4997 != ZONE_SUBPROC_OK) { 4998 zerror(gettext("could not update zone")); 4999 update_res = Z_ERR; 5000 } 5001 5002 zarg.cmd = Z_UNMOUNT; 5003 if (call_zoneadmd(target_zone, &zarg) != 0) { 5004 zerror(gettext("could not unmount zone")); 5005 return (Z_ERR); 5006 } 5007 5008 /* 5009 * If the update script within the scratch zone failed for some reason 5010 * we will now leave the zone in the incomplete state since we no 5011 * longer know the state of the files within the zonepath. 5012 */ 5013 if (update_res == Z_ERR) 5014 return (Z_ERR); 5015 5016 zonecfg_rm_detached(handle, B_FALSE); 5017 5018 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 5019 errno = err; 5020 zperror(gettext("could not set state"), B_TRUE); 5021 return (Z_ERR); 5022 } 5023 5024 return (Z_OK); 5025 5026fail: 5027 zarg.cmd = Z_UNMOUNT; 5028 if (call_zoneadmd(target_zone, &zarg) != 0) 5029 zerror(gettext("could not unmount zone")); 5030 5031 /* We reset the state since the zone wasn't modified yet. */ 5032 if ((err = zone_set_state(target_zone, ZONE_STATE_CONFIGURED)) 5033 != Z_OK) { 5034 errno = err; 5035 zperror(gettext("could not reset state"), B_TRUE); 5036 } 5037 5038 return (Z_ERR); 5039} 5040 5041/* ARGSUSED */ 5042static void 5043sigcleanup(int sig) 5044{ 5045 attach_interupted = B_TRUE; 5046} 5047 5048 5049static int |
|
4902attach_func(int argc, char *argv[]) 4903{ 4904 int lockfd; 4905 int err, arg; 4906 boolean_t force = B_FALSE; 4907 zone_dochandle_t handle; 4908 zone_dochandle_t athandle = NULL; 4909 char zonepath[MAXPATHLEN]; 4910 char brand[MAXNAMELEN], atbrand[MAXNAMELEN]; 4911 char cmdbuf[MAXPATHLEN]; 4912 boolean_t execute = B_TRUE; 4913 boolean_t retried = B_FALSE; | 5050attach_func(int argc, char *argv[]) 5051{ 5052 int lockfd; 5053 int err, arg; 5054 boolean_t force = B_FALSE; 5055 zone_dochandle_t handle; 5056 zone_dochandle_t athandle = NULL; 5057 char zonepath[MAXPATHLEN]; 5058 char brand[MAXNAMELEN], atbrand[MAXNAMELEN]; 5059 char cmdbuf[MAXPATHLEN]; 5060 boolean_t execute = B_TRUE; 5061 boolean_t retried = B_FALSE; |
5062 boolean_t update = B_FALSE; |
|
4914 char *manifest_path; 4915 brand_handle_t bh = NULL; 4916 4917 if (zonecfg_in_alt_root()) { 4918 zerror(gettext("cannot attach zone in alternate root")); 4919 return (Z_ERR); 4920 } 4921 4922 optind = 0; | 5063 char *manifest_path; 5064 brand_handle_t bh = NULL; 5065 5066 if (zonecfg_in_alt_root()) { 5067 zerror(gettext("cannot attach zone in alternate root")); 5068 return (Z_ERR); 5069 } 5070 5071 optind = 0; |
4923 if ((arg = getopt(argc, argv, "?Fn:")) != EOF) { | 5072 if ((arg = getopt(argc, argv, "?Fn:u")) != EOF) { |
4924 switch (arg) { 4925 case '?': 4926 sub_usage(SHELP_ATTACH, CMD_ATTACH); 4927 return (optopt == '?' ? Z_OK : Z_USAGE); 4928 case 'F': 4929 force = B_TRUE; 4930 break; 4931 case 'n': 4932 execute = B_FALSE; 4933 manifest_path = optarg; 4934 break; | 5073 switch (arg) { 5074 case '?': 5075 sub_usage(SHELP_ATTACH, CMD_ATTACH); 5076 return (optopt == '?' ? Z_OK : Z_USAGE); 5077 case 'F': 5078 force = B_TRUE; 5079 break; 5080 case 'n': 5081 execute = B_FALSE; 5082 manifest_path = optarg; 5083 break; |
5084 case 'u': 5085 update = B_TRUE; 5086 break; |
|
4935 default: 4936 sub_usage(SHELP_ATTACH, CMD_ATTACH); 4937 return (Z_USAGE); 4938 } 4939 } 4940 | 5087 default: 5088 sub_usage(SHELP_ATTACH, CMD_ATTACH); 5089 return (Z_USAGE); 5090 } 5091 } 5092 |
5093 /* dry-run and update flags are mutually exclusive */ 5094 if (!execute && update) { 5095 zerror(gettext("-n and -u flags are mutually exclusive")); 5096 return (Z_ERR); 5097 } 5098 |
|
4941 /* 4942 * If the no-execute option was specified, we need to branch down 4943 * a completely different path since there is no zone required to be 4944 * configured for this option. 4945 */ 4946 if (!execute) 4947 return (dryrun_attach(manifest_path, argv)); 4948 --- 118 unchanged lines hidden (view full) --- 5067 5068 if (strcmp(atbrand, brand) != NULL) { 5069 err = Z_ERR; 5070 zerror(gettext("Trying to attach a '%s' zone to a '%s' " 5071 "configuration."), atbrand, brand); 5072 goto done; 5073 } 5074 | 5099 /* 5100 * If the no-execute option was specified, we need to branch down 5101 * a completely different path since there is no zone required to be 5102 * configured for this option. 5103 */ 5104 if (!execute) 5105 return (dryrun_attach(manifest_path, argv)); 5106 --- 118 unchanged lines hidden (view full) --- 5225 5226 if (strcmp(atbrand, brand) != NULL) { 5227 err = Z_ERR; 5228 zerror(gettext("Trying to attach a '%s' zone to a '%s' " 5229 "configuration."), atbrand, brand); 5230 goto done; 5231 } 5232 |
5075 /* sw_cmp prints error msgs as necessary */ 5076 if ((err = sw_cmp(handle, athandle, SW_CMP_NONE)) != Z_OK) 5077 goto done; | 5233 /* 5234 * If we're doing an update on attach, and the zone does need to be 5235 * updated, then run the update. 5236 */ 5237 if (update) { 5238 char fname[MAXPATHLEN]; |
5078 | 5239 |
5079 if ((err = dev_fix(athandle)) != Z_OK) 5080 goto done; | 5240 (void) sigset(SIGINT, sigcleanup); |
5081 | 5241 |
5242 if ((err = sw_up_to_date(handle, athandle, zonepath)) != Z_OK) { 5243 if (err != Z_FATAL && !attach_interupted) { 5244 err = Z_FATAL; 5245 err = attach_update(handle, zonepath); 5246 } 5247 if (!attach_interupted || err == Z_OK) 5248 goto done; 5249 } 5250 5251 (void) sigset(SIGINT, SIG_DFL); 5252 5253 /* clean up data files left behind by sw_up_to_date() */ 5254 (void) snprintf(fname, sizeof (fname), "%s/pkg_add", zonepath); 5255 (void) unlink(fname); 5256 (void) snprintf(fname, sizeof (fname), "%s/pkg_rm", zonepath); 5257 (void) unlink(fname); 5258 5259 if (attach_interupted) { 5260 err = Z_FATAL; 5261 goto done; 5262 } 5263 5264 } else { 5265 /* sw_cmp prints error msgs as necessary */ 5266 if ((err = sw_cmp(handle, athandle, SW_CMP_NONE)) != Z_OK) 5267 goto done; 5268 5269 if ((err = dev_fix(athandle)) != Z_OK) 5270 goto done; 5271 } 5272 |
|
5082forced: 5083 5084 zonecfg_rm_detached(handle, force); 5085 5086 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 5087 errno = err; 5088 zperror(gettext("could not reset state"), B_TRUE); 5089 } --- 231 unchanged lines hidden (view full) --- 5321 5322 if (sanity_check(target_zone, CMD_MOUNT, B_FALSE, B_FALSE, force) 5323 != Z_OK) 5324 return (Z_ERR); 5325 if (verify_details(CMD_MOUNT, argv) != Z_OK) 5326 return (Z_ERR); 5327 5328 zarg.cmd = force ? Z_FORCEMOUNT : Z_MOUNT; | 5273forced: 5274 5275 zonecfg_rm_detached(handle, force); 5276 5277 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 5278 errno = err; 5279 zperror(gettext("could not reset state"), B_TRUE); 5280 } --- 231 unchanged lines hidden (view full) --- 5512 5513 if (sanity_check(target_zone, CMD_MOUNT, B_FALSE, B_FALSE, force) 5514 != Z_OK) 5515 return (Z_ERR); 5516 if (verify_details(CMD_MOUNT, argv) != Z_OK) 5517 return (Z_ERR); 5518 5519 zarg.cmd = force ? Z_FORCEMOUNT : Z_MOUNT; |
5520 zarg.bootbuf[0] = '\0'; |
|
5329 if (call_zoneadmd(target_zone, &zarg) != 0) { 5330 zerror(gettext("call to %s failed"), "zoneadmd"); 5331 return (Z_ERR); 5332 } 5333 return (Z_OK); 5334} 5335 5336/* ARGSUSED */ --- 514 unchanged lines hidden --- | 5521 if (call_zoneadmd(target_zone, &zarg) != 0) { 5522 zerror(gettext("call to %s failed"), "zoneadmd"); 5523 return (Z_ERR); 5524 } 5525 return (Z_OK); 5526} 5527 5528/* ARGSUSED */ --- 514 unchanged lines hidden --- |