Print this page
Merge cleanup from previous six commits
OS-200 need a better mechanism for storing persistent zone_did
OS-2564 zone boot failed: could not start zoneadmd
OS-1763 mount of /etc/svc/volatile failed: Device busy
OS-511 make zonecfg device resource extensible, like the net resource
OS-224 add more zonecfg net properties


 128 
 129 zlog_t logsys;
 130 
 131 mutex_t lock = DEFAULTMUTEX;    /* to serialize stuff */
 132 mutex_t msglock = DEFAULTMUTEX; /* for calling setlocale() */
 133 
 134 static sema_t scratch_sem;      /* for scratch zones */
 135 
 136 static char     zone_door_path[MAXPATHLEN];
 137 static int      zone_door = -1;
 138 
 139 boolean_t in_death_throes = B_FALSE;    /* daemon is dying */
 140 boolean_t bringup_failure_recovery = B_FALSE; /* ignore certain failures */
 141 
 142 #if !defined(TEXT_DOMAIN)               /* should be defined by cc -D */
 143 #define TEXT_DOMAIN     "SYS_TEST"      /* Use this only if it wasn't */
 144 #endif
 145 
 146 #define DEFAULT_LOCALE  "C"
 147 



 148 static const char *
 149 z_cmd_name(zone_cmd_t zcmd)
 150 {
 151         /* This list needs to match the enum in sys/zone.h */
 152         static const char *zcmdstr[] = {
 153                 "ready", "boot", "forceboot", "reboot", "halt",
 154                 "note_uninstalling", "mount", "forcemount", "unmount",
 155                 "shutdown"
 156         };
 157 
 158         if (zcmd >= sizeof (zcmdstr) / sizeof (*zcmdstr))
 159                 return ("unknown");
 160         else
 161                 return (zcmdstr[(int)zcmd]);
 162 }
 163 
 164 static char *
 165 get_execbasename(char *execfullname)
 166 {
 167         char *last_slash, *execbasename;


 664                             "%s%s is not a valid mount point", rootpath, dir);
 665                         return (-1);
 666                 }
 667         }
 668 
 669         if ((tmpl_fd = init_template()) == -1) {
 670                 zerror(zlogp, B_TRUE, "failed to create contract");
 671                 return (-1);
 672         }
 673 
 674         if ((child = fork()) == -1) {
 675                 (void) ct_tmpl_clear(tmpl_fd);
 676                 (void) close(tmpl_fd);
 677                 zerror(zlogp, B_TRUE, "failed to fork");
 678                 return (-1);
 679 
 680         } else if (child == 0) {        /* child */
 681                 char opt_buf[MAX_MNTOPT_STR];
 682                 int optlen = 0;
 683                 int mflag = MS_DATA;


 684 
 685                 (void) ct_tmpl_clear(tmpl_fd);
 686                 /*
 687                  * Even though there are no procs running in the zone, we
 688                  * do this for paranoia's sake.
 689                  */
 690                 (void) closefrom(0);
 691 
 692                 if (zone_enter(zoneid) == -1) {
 693                         _exit(errno);
 694                 }
 695                 if (opt != NULL) {
 696                         /*
 697                          * The mount() system call is incredibly annoying.
 698                          * If options are specified, we need to copy them
 699                          * into a temporary buffer since the mount() system
 700                          * call will overwrite the options string.  It will
 701                          * also fail if the new option string it wants to
 702                          * write is bigger than the one we passed in, so
 703                          * you must pass in a buffer of the maximum possible
 704                          * option string length.  sigh.
 705                          */
 706                         (void) strlcpy(opt_buf, opt, sizeof (opt_buf));
 707                         opt = opt_buf;
 708                         optlen = MAX_MNTOPT_STR;
 709                         mflag = MS_OPTIONSTR;
 710                 }
 711                 if (mount(spec, dir, mflag, fstype, NULL, 0, opt, optlen) != 0)
 712                         _exit(errno);
 713                 _exit(0);















 714         }


 715 
 716         /* parent */
 717         if (contract_latest(&ct) == -1)
 718                 ct = -1;
 719         (void) ct_tmpl_clear(tmpl_fd);
 720         (void) close(tmpl_fd);
 721         if (waitpid(child, &child_status, 0) != child) {
 722                 /* unexpected: we must have been signalled */
 723                 (void) contract_abandon_id(ct);
 724                 return (-1);
 725         }
 726         (void) contract_abandon_id(ct);
 727         if (WEXITSTATUS(child_status) != 0) {
 728                 errno = WEXITSTATUS(child_status);
 729                 zerror(zlogp, B_TRUE, "mount of %s failed", dir);
 730                 return (-1);
 731         }
 732 
 733         return (0);
 734 }
 735 
 736 /*













































































































 737  * If retstr is not NULL, the output of the subproc is returned in the str,
 738  * otherwise it is output using zerror().  Any memory allocated for retstr
 739  * should be freed by the caller.
 740  */
 741 int
 742 do_subproc(zlog_t *zlogp, char *cmdbuf, char **retstr)
 743 {
 744         char buf[1024];         /* arbitrary large amount */
 745         char *inbuf;
 746         FILE *file;
 747         int status;
 748         int rd_cnt;
 749 
 750         if (retstr != NULL) {
 751                 if ((*retstr = malloc(1024)) == NULL) {
 752                         zerror(zlogp, B_FALSE, "out of memory");
 753                         return (-1);
 754                 }
 755                 inbuf = *retstr;
 756                 rd_cnt = 0;
 757         } else {
 758                 inbuf = buf;
 759         }
 760 





 761         file = popen(cmdbuf, "r");
 762         if (file == NULL) {
 763                 zerror(zlogp, B_TRUE, "could not launch: %s", cmdbuf);
 764                 return (-1);
 765         }
 766 
 767         while (fgets(inbuf, 1024, file) != NULL) {
 768                 if (retstr == NULL) {
 769                         if (zlogp != &logsys)
 770                                 zerror(zlogp, B_FALSE, "%s", inbuf);
 771                 } else {
 772                         char *p;
 773 
 774                         rd_cnt += 1024 - 1;
 775                         if ((p = realloc(*retstr, rd_cnt + 1024)) == NULL) {
 776                                 zerror(zlogp, B_FALSE, "out of memory");
 777                                 (void) pclose(file);
 778                                 return (-1);
 779                         }
 780 


1446                 zstate = ZONE_STATE_INSTALLED;
1447 
1448         switch (zstate) {
1449         case ZONE_STATE_CONFIGURED:
1450         case ZONE_STATE_INCOMPLETE:
1451                 /*
1452                  * Not our area of expertise; we just print a nice message
1453                  * and die off.
1454                  */
1455                 zerror(zlogp, B_FALSE,
1456                     "%s operation is invalid for zones in state '%s'",
1457                     z_cmd_name(cmd), zone_state_str(zstate));
1458                 break;
1459 
1460         case ZONE_STATE_INSTALLED:
1461                 switch (cmd) {
1462                 case Z_READY:
1463                         rval = zone_ready(zlogp, Z_MNT_BOOT, zstate);
1464                         if (rval == 0)
1465                                 eventstream_write(Z_EVT_ZONE_READIED);

1466                         break;
1467                 case Z_BOOT:
1468                 case Z_FORCEBOOT:
1469                         eventstream_write(Z_EVT_ZONE_BOOTING);
1470                         if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate))
1471                             == 0) {
1472                                 rval = zone_bootup(zlogp, zargp->bootbuf,
1473                                     zstate);
1474                         }
1475                         audit_put_record(zlogp, uc, rval, "boot");

1476                         if (rval != 0) {
1477                                 bringup_failure_recovery = B_TRUE;
1478                                 (void) zone_halt(zlogp, B_FALSE, B_FALSE,
1479                                     zstate);
1480                                 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1481                         }
1482                         break;
1483                 case Z_SHUTDOWN:
1484                 case Z_HALT:
1485                         if (kernelcall) /* Invalid; can't happen */
1486                                 abort();
1487                         /*
1488                          * We could have two clients racing to halt this
1489                          * zone; the second client loses, but his request
1490                          * doesn't fail, since the zone is now in the desired
1491                          * state.
1492                          */
1493                         zerror(zlogp, B_FALSE, "zone is already halted");
1494                         rval = 0;
1495                         break;


1578                 break;
1579 
1580         case ZONE_STATE_READY:
1581                 switch (cmd) {
1582                 case Z_READY:
1583                         /*
1584                          * We could have two clients racing to ready this
1585                          * zone; the second client loses, but his request
1586                          * doesn't fail, since the zone is now in the desired
1587                          * state.
1588                          */
1589                         zerror(zlogp, B_FALSE, "zone is already ready");
1590                         rval = 0;
1591                         break;
1592                 case Z_BOOT:
1593                         (void) strlcpy(boot_args, zargp->bootbuf,
1594                             sizeof (boot_args));
1595                         eventstream_write(Z_EVT_ZONE_BOOTING);
1596                         rval = zone_bootup(zlogp, zargp->bootbuf, zstate);
1597                         audit_put_record(zlogp, uc, rval, "boot");

1598                         if (rval != 0) {
1599                                 bringup_failure_recovery = B_TRUE;
1600                                 (void) zone_halt(zlogp, B_FALSE, B_TRUE,
1601                                     zstate);
1602                                 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1603                         }
1604                         boot_args[0] = '\0';
1605                         break;
1606                 case Z_HALT:
1607                         if (kernelcall) /* Invalid; can't happen */
1608                                 abort();
1609                         if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate))
1610                             != 0)
1611                                 break;

1612                         eventstream_write(Z_EVT_ZONE_HALTED);
1613                         break;
1614                 case Z_SHUTDOWN:
1615                 case Z_REBOOT:
1616                 case Z_NOTE_UNINSTALLING:
1617                 case Z_MOUNT:
1618                 case Z_UNMOUNT:
1619                         if (kernelcall) /* Invalid; can't happen */
1620                                 abort();
1621                         zerror(zlogp, B_FALSE, "%s operation is invalid "
1622                             "for zones in state '%s'", z_cmd_name(cmd),
1623                             zone_state_str(zstate));
1624                         rval = -1;
1625                         break;
1626                 }
1627                 break;
1628 
1629         case ZONE_STATE_MOUNTED:
1630                 switch (cmd) {
1631                 case Z_UNMOUNT:


1639                         break;
1640                 default:
1641                         if (kernelcall) /* Invalid; can't happen */
1642                                 abort();
1643                         zerror(zlogp, B_FALSE, "%s operation is invalid "
1644                             "for zones in state '%s'", z_cmd_name(cmd),
1645                             zone_state_str(zstate));
1646                         rval = -1;
1647                         break;
1648                 }
1649                 break;
1650 
1651         case ZONE_STATE_RUNNING:
1652         case ZONE_STATE_SHUTTING_DOWN:
1653         case ZONE_STATE_DOWN:
1654                 switch (cmd) {
1655                 case Z_READY:
1656                         if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate))
1657                             != 0)
1658                                 break;

1659                         if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) == 0)
1660                                 eventstream_write(Z_EVT_ZONE_READIED);
1661                         else
1662                                 eventstream_write(Z_EVT_ZONE_HALTED);
1663                         break;
1664                 case Z_BOOT:
1665                         /*
1666                          * We could have two clients racing to boot this
1667                          * zone; the second client loses, but his request
1668                          * doesn't fail, since the zone is now in the desired
1669                          * state.
1670                          */
1671                         zerror(zlogp, B_FALSE, "zone is already booted");
1672                         rval = 0;
1673                         break;
1674                 case Z_HALT:
1675                         if (kernelcall) {
1676                                 log_init_exit(init_status);
1677                         } else {
1678                                 log_init_exit(-1);
1679                         }
1680                         if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate))
1681                             != 0)
1682                                 break;
1683                         eventstream_write(Z_EVT_ZONE_HALTED);

1684                         break;
1685                 case Z_REBOOT:
1686                         (void) strlcpy(boot_args, zargp->bootbuf,
1687                             sizeof (boot_args));
1688                         eventstream_write(Z_EVT_ZONE_REBOOTING);
1689                         if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate))
1690                             != 0) {
1691                                 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1692                                 boot_args[0] = '\0';
1693                                 break;
1694                         }
1695                         if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate))
1696                             != 0) {

1697                                 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1698                                 boot_args[0] = '\0';
1699                                 break;
1700                         }
1701                         rval = zone_bootup(zlogp, zargp->bootbuf, zstate);
1702                         audit_put_record(zlogp, uc, rval, "reboot");
1703                         if (rval != 0) {
1704                                 (void) zone_halt(zlogp, B_FALSE, B_TRUE,
1705                                     zstate);
1706                                 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1707                         }
1708                         boot_args[0] = '\0';
1709                         break;
1710                 case Z_SHUTDOWN:
1711                         if ((rval = zone_graceful_shutdown(zlogp)) == 0) {
1712                                 wait_shut = B_TRUE;
1713                         }
1714                         break;
1715                 case Z_NOTE_UNINSTALLING:
1716                 case Z_MOUNT:




 128 
 129 zlog_t logsys;
 130 
 131 mutex_t lock = DEFAULTMUTEX;    /* to serialize stuff */
 132 mutex_t msglock = DEFAULTMUTEX; /* for calling setlocale() */
 133 
 134 static sema_t scratch_sem;      /* for scratch zones */
 135 
 136 static char     zone_door_path[MAXPATHLEN];
 137 static int      zone_door = -1;
 138 
 139 boolean_t in_death_throes = B_FALSE;    /* daemon is dying */
 140 boolean_t bringup_failure_recovery = B_FALSE; /* ignore certain failures */
 141 
 142 #if !defined(TEXT_DOMAIN)               /* should be defined by cc -D */
 143 #define TEXT_DOMAIN     "SYS_TEST"      /* Use this only if it wasn't */
 144 #endif
 145 
 146 #define DEFAULT_LOCALE  "C"
 147 
 148 #define RSRC_NET        "net"
 149 #define RSRC_DEV        "device"
 150 
 151 static const char *
 152 z_cmd_name(zone_cmd_t zcmd)
 153 {
 154         /* This list needs to match the enum in sys/zone.h */
 155         static const char *zcmdstr[] = {
 156                 "ready", "boot", "forceboot", "reboot", "halt",
 157                 "note_uninstalling", "mount", "forcemount", "unmount",
 158                 "shutdown"
 159         };
 160 
 161         if (zcmd >= sizeof (zcmdstr) / sizeof (*zcmdstr))
 162                 return ("unknown");
 163         else
 164                 return (zcmdstr[(int)zcmd]);
 165 }
 166 
 167 static char *
 168 get_execbasename(char *execfullname)
 169 {
 170         char *last_slash, *execbasename;


 667                             "%s%s is not a valid mount point", rootpath, dir);
 668                         return (-1);
 669                 }
 670         }
 671 
 672         if ((tmpl_fd = init_template()) == -1) {
 673                 zerror(zlogp, B_TRUE, "failed to create contract");
 674                 return (-1);
 675         }
 676 
 677         if ((child = fork()) == -1) {
 678                 (void) ct_tmpl_clear(tmpl_fd);
 679                 (void) close(tmpl_fd);
 680                 zerror(zlogp, B_TRUE, "failed to fork");
 681                 return (-1);
 682 
 683         } else if (child == 0) {        /* child */
 684                 char opt_buf[MAX_MNTOPT_STR];
 685                 int optlen = 0;
 686                 int mflag = MS_DATA;
 687                 int i;
 688                 int ret;
 689 
 690                 (void) ct_tmpl_clear(tmpl_fd);
 691                 /*
 692                  * Even though there are no procs running in the zone, we
 693                  * do this for paranoia's sake.
 694                  */
 695                 (void) closefrom(0);
 696 
 697                 if (zone_enter(zoneid) == -1) {
 698                         _exit(errno);
 699                 }
 700                 if (opt != NULL) {
 701                         /*
 702                          * The mount() system call is incredibly annoying.
 703                          * If options are specified, we need to copy them
 704                          * into a temporary buffer since the mount() system
 705                          * call will overwrite the options string.  It will
 706                          * also fail if the new option string it wants to
 707                          * write is bigger than the one we passed in, so
 708                          * you must pass in a buffer of the maximum possible
 709                          * option string length.  sigh.
 710                          */
 711                         (void) strlcpy(opt_buf, opt, sizeof (opt_buf));
 712                         opt = opt_buf;
 713                         optlen = MAX_MNTOPT_STR;
 714                         mflag = MS_OPTIONSTR;
 715                 }
 716 
 717                 /*
 718                  * There is an obscure race condition which can cause mount
 719                  * to return EBUSY. This happens for example on the mount
 720                  * of the zone's /etc/svc/volatile file system if there is
 721                  * a GZ process running svcs -Z, which will touch the
 722                  * mountpoint, just as we're trying to do the mount. To cope
 723                  * with this, we retry up to 3 times to let this transient
 724                  * process get out of the way.
 725                  */
 726                 for (i = 0; i < 3; i++) {
 727                         ret = 0;
 728                         if (mount(spec, dir, mflag, fstype, NULL, 0, opt,
 729                             optlen) != 0)
 730                                 ret = errno;
 731                         if (ret != EBUSY)
 732                                 break;
 733                         (void) sleep(1);
 734                 }
 735                 _exit(ret);
 736         }
 737 
 738         /* parent */
 739         if (contract_latest(&ct) == -1)
 740                 ct = -1;
 741         (void) ct_tmpl_clear(tmpl_fd);
 742         (void) close(tmpl_fd);
 743         if (waitpid(child, &child_status, 0) != child) {
 744                 /* unexpected: we must have been signalled */
 745                 (void) contract_abandon_id(ct);
 746                 return (-1);
 747         }
 748         (void) contract_abandon_id(ct);
 749         if (WEXITSTATUS(child_status) != 0) {
 750                 errno = WEXITSTATUS(child_status);
 751                 zerror(zlogp, B_TRUE, "mount of %s failed", dir);
 752                 return (-1);
 753         }
 754 
 755         return (0);
 756 }
 757 
 758 /*
 759  * env variable name format
 760  *      _ZONECFG;{resource name};{identifying attr. name};{property name}
 761  */
 762 static void
 763 set_zonecfg_env(char *rsrc, char *attr, char *name, char *val)
 764 {
 765         char *p;
 766         /* Enough for maximal name, rsrc + attr, & slop for ZONECFG & _'s */
 767         char nm[2 * MAXNAMELEN + 32];
 768 
 769         if (attr == NULL)
 770                 (void) snprintf(nm, sizeof (nm), "_ZONECFG_%s_%s", rsrc,
 771                     name);
 772         else
 773                 (void) snprintf(nm, sizeof (nm), "_ZONECFG_%s_%s_%s", rsrc,
 774                     attr, name);
 775 
 776         p = nm;
 777         while ((p = strchr(p, '-')) != NULL)
 778                 *p++ = '_';
 779 
 780         (void) setenv(nm, val, 1);
 781 }
 782 
 783 /*
 784  * Export zonecfg network and device properties into environment for the boot
 785  * and state change hooks.
 786  * If debug is true, export the brand hook debug env. variable as well.
 787  *
 788  * We could export more of the config in the future, as necessary.
 789  */
 790 static int
 791 setup_subproc_env()
 792 {
 793         int res;
 794         zone_dochandle_t handle;
 795         struct zone_nwiftab ntab;
 796         struct zone_devtab dtab;
 797         char net_resources[MAXNAMELEN * 2];
 798         char dev_resources[MAXNAMELEN * 2];
 799 
 800         if ((handle = zonecfg_init_handle()) == NULL)
 801                 exit(Z_NOMEM);
 802 
 803         if ((res = zonecfg_get_handle(zone_name, handle)) != Z_OK)
 804                 goto done;
 805 
 806         if ((res = zonecfg_setnwifent(handle)) != Z_OK)
 807                 goto done;
 808 
 809         while (zonecfg_getnwifent(handle, &ntab) == Z_OK) {
 810                 struct zone_res_attrtab *rap;
 811                 char *phys;
 812 
 813                 phys = ntab.zone_nwif_physical;
 814 
 815                 (void) strlcat(net_resources, phys, sizeof (net_resources));
 816                 (void) strlcat(net_resources, " ", sizeof (net_resources));
 817 
 818                 set_zonecfg_env(RSRC_NET, phys, "physical", phys);
 819 
 820                 set_zonecfg_env(RSRC_NET, phys, "address",
 821                     ntab.zone_nwif_address);
 822                 set_zonecfg_env(RSRC_NET, phys, "allowed-address",
 823                     ntab.zone_nwif_allowed_address);
 824                 set_zonecfg_env(RSRC_NET, phys, "defrouter",
 825                     ntab.zone_nwif_defrouter);
 826                 set_zonecfg_env(RSRC_NET, phys, "global-nic",
 827                     ntab.zone_nwif_gnic);
 828                 set_zonecfg_env(RSRC_NET, phys, "mac-addr", ntab.zone_nwif_mac);
 829                 set_zonecfg_env(RSRC_NET, phys, "vlan-id",
 830                     ntab.zone_nwif_vlan_id);
 831 
 832                 for (rap = ntab.zone_nwif_attrp; rap != NULL;
 833                     rap = rap->zone_res_attr_next)
 834                         set_zonecfg_env(RSRC_NET, phys, rap->zone_res_attr_name,
 835                             rap->zone_res_attr_value);
 836         }
 837 
 838         (void) zonecfg_endnwifent(handle);
 839 
 840         if ((res = zonecfg_setdevent(handle)) != Z_OK)
 841                 goto done;
 842 
 843         while (zonecfg_getdevent(handle, &dtab) == Z_OK) {
 844                 struct zone_res_attrtab *rap;
 845                 char *match;
 846 
 847                 match = dtab.zone_dev_match;
 848 
 849                 (void) strlcat(dev_resources, match, sizeof (dev_resources));
 850                 (void) strlcat(dev_resources, " ", sizeof (dev_resources));
 851 
 852                 for (rap = dtab.zone_dev_attrp; rap != NULL;
 853                     rap = rap->zone_res_attr_next)
 854                         set_zonecfg_env(RSRC_DEV, match,
 855                             rap->zone_res_attr_name, rap->zone_res_attr_value);
 856         }
 857 
 858         (void) zonecfg_enddevent(handle);
 859 
 860         res = Z_OK;
 861 
 862 done:
 863         zonecfg_fini_handle(handle);
 864         return (res);
 865 }
 866 
 867 /*
 868  * If retstr is not NULL, the output of the subproc is returned in the str,
 869  * otherwise it is output using zerror().  Any memory allocated for retstr
 870  * should be freed by the caller.
 871  */
 872 int
 873 do_subproc(zlog_t *zlogp, char *cmdbuf, char **retstr)
 874 {
 875         char buf[1024];         /* arbitrary large amount */
 876         char *inbuf;
 877         FILE *file;
 878         int status;
 879         int rd_cnt;
 880 
 881         if (retstr != NULL) {
 882                 if ((*retstr = malloc(1024)) == NULL) {
 883                         zerror(zlogp, B_FALSE, "out of memory");
 884                         return (-1);
 885                 }
 886                 inbuf = *retstr;
 887                 rd_cnt = 0;
 888         } else {
 889                 inbuf = buf;
 890         }
 891 
 892         if (setup_subproc_env() != Z_OK) {
 893                 zerror(zlogp, B_FALSE, "failed to setup environment");
 894                 return (-1);
 895         }
 896 
 897         file = popen(cmdbuf, "r");
 898         if (file == NULL) {
 899                 zerror(zlogp, B_TRUE, "could not launch: %s", cmdbuf);
 900                 return (-1);
 901         }
 902 
 903         while (fgets(inbuf, 1024, file) != NULL) {
 904                 if (retstr == NULL) {
 905                         if (zlogp != &logsys)
 906                                 zerror(zlogp, B_FALSE, "%s", inbuf);
 907                 } else {
 908                         char *p;
 909 
 910                         rd_cnt += 1024 - 1;
 911                         if ((p = realloc(*retstr, rd_cnt + 1024)) == NULL) {
 912                                 zerror(zlogp, B_FALSE, "out of memory");
 913                                 (void) pclose(file);
 914                                 return (-1);
 915                         }
 916 


1582                 zstate = ZONE_STATE_INSTALLED;
1583 
1584         switch (zstate) {
1585         case ZONE_STATE_CONFIGURED:
1586         case ZONE_STATE_INCOMPLETE:
1587                 /*
1588                  * Not our area of expertise; we just print a nice message
1589                  * and die off.
1590                  */
1591                 zerror(zlogp, B_FALSE,
1592                     "%s operation is invalid for zones in state '%s'",
1593                     z_cmd_name(cmd), zone_state_str(zstate));
1594                 break;
1595 
1596         case ZONE_STATE_INSTALLED:
1597                 switch (cmd) {
1598                 case Z_READY:
1599                         rval = zone_ready(zlogp, Z_MNT_BOOT, zstate);
1600                         if (rval == 0)
1601                                 eventstream_write(Z_EVT_ZONE_READIED);
1602                         zcons_statechanged();
1603                         break;
1604                 case Z_BOOT:
1605                 case Z_FORCEBOOT:
1606                         eventstream_write(Z_EVT_ZONE_BOOTING);
1607                         if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate))
1608                             == 0) {
1609                                 rval = zone_bootup(zlogp, zargp->bootbuf,
1610                                     zstate);
1611                         }
1612                         audit_put_record(zlogp, uc, rval, "boot");
1613                         zcons_statechanged();
1614                         if (rval != 0) {
1615                                 bringup_failure_recovery = B_TRUE;
1616                                 (void) zone_halt(zlogp, B_FALSE, B_FALSE,
1617                                     zstate);
1618                                 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1619                         }
1620                         break;
1621                 case Z_SHUTDOWN:
1622                 case Z_HALT:
1623                         if (kernelcall) /* Invalid; can't happen */
1624                                 abort();
1625                         /*
1626                          * We could have two clients racing to halt this
1627                          * zone; the second client loses, but his request
1628                          * doesn't fail, since the zone is now in the desired
1629                          * state.
1630                          */
1631                         zerror(zlogp, B_FALSE, "zone is already halted");
1632                         rval = 0;
1633                         break;


1716                 break;
1717 
1718         case ZONE_STATE_READY:
1719                 switch (cmd) {
1720                 case Z_READY:
1721                         /*
1722                          * We could have two clients racing to ready this
1723                          * zone; the second client loses, but his request
1724                          * doesn't fail, since the zone is now in the desired
1725                          * state.
1726                          */
1727                         zerror(zlogp, B_FALSE, "zone is already ready");
1728                         rval = 0;
1729                         break;
1730                 case Z_BOOT:
1731                         (void) strlcpy(boot_args, zargp->bootbuf,
1732                             sizeof (boot_args));
1733                         eventstream_write(Z_EVT_ZONE_BOOTING);
1734                         rval = zone_bootup(zlogp, zargp->bootbuf, zstate);
1735                         audit_put_record(zlogp, uc, rval, "boot");
1736                         zcons_statechanged();
1737                         if (rval != 0) {
1738                                 bringup_failure_recovery = B_TRUE;
1739                                 (void) zone_halt(zlogp, B_FALSE, B_TRUE,
1740                                     zstate);
1741                                 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1742                         }
1743                         boot_args[0] = '\0';
1744                         break;
1745                 case Z_HALT:
1746                         if (kernelcall) /* Invalid; can't happen */
1747                                 abort();
1748                         if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate))
1749                             != 0)
1750                                 break;
1751                         zcons_statechanged();
1752                         eventstream_write(Z_EVT_ZONE_HALTED);
1753                         break;
1754                 case Z_SHUTDOWN:
1755                 case Z_REBOOT:
1756                 case Z_NOTE_UNINSTALLING:
1757                 case Z_MOUNT:
1758                 case Z_UNMOUNT:
1759                         if (kernelcall) /* Invalid; can't happen */
1760                                 abort();
1761                         zerror(zlogp, B_FALSE, "%s operation is invalid "
1762                             "for zones in state '%s'", z_cmd_name(cmd),
1763                             zone_state_str(zstate));
1764                         rval = -1;
1765                         break;
1766                 }
1767                 break;
1768 
1769         case ZONE_STATE_MOUNTED:
1770                 switch (cmd) {
1771                 case Z_UNMOUNT:


1779                         break;
1780                 default:
1781                         if (kernelcall) /* Invalid; can't happen */
1782                                 abort();
1783                         zerror(zlogp, B_FALSE, "%s operation is invalid "
1784                             "for zones in state '%s'", z_cmd_name(cmd),
1785                             zone_state_str(zstate));
1786                         rval = -1;
1787                         break;
1788                 }
1789                 break;
1790 
1791         case ZONE_STATE_RUNNING:
1792         case ZONE_STATE_SHUTTING_DOWN:
1793         case ZONE_STATE_DOWN:
1794                 switch (cmd) {
1795                 case Z_READY:
1796                         if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate))
1797                             != 0)
1798                                 break;
1799                         zcons_statechanged();
1800                         if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) == 0)
1801                                 eventstream_write(Z_EVT_ZONE_READIED);
1802                         else
1803                                 eventstream_write(Z_EVT_ZONE_HALTED);
1804                         break;
1805                 case Z_BOOT:
1806                         /*
1807                          * We could have two clients racing to boot this
1808                          * zone; the second client loses, but his request
1809                          * doesn't fail, since the zone is now in the desired
1810                          * state.
1811                          */
1812                         zerror(zlogp, B_FALSE, "zone is already booted");
1813                         rval = 0;
1814                         break;
1815                 case Z_HALT:
1816                         if (kernelcall) {
1817                                 log_init_exit(init_status);
1818                         } else {
1819                                 log_init_exit(-1);
1820                         }
1821                         if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate))
1822                             != 0)
1823                                 break;
1824                         eventstream_write(Z_EVT_ZONE_HALTED);
1825                         zcons_statechanged();
1826                         break;
1827                 case Z_REBOOT:
1828                         (void) strlcpy(boot_args, zargp->bootbuf,
1829                             sizeof (boot_args));
1830                         eventstream_write(Z_EVT_ZONE_REBOOTING);
1831                         if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate))
1832                             != 0) {
1833                                 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1834                                 boot_args[0] = '\0';
1835                                 break;
1836                         }
1837                         zcons_statechanged();
1838                         if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) !=
1839                             0) {
1840                                 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1841                                 boot_args[0] = '\0';
1842                                 break;
1843                         }
1844                         rval = zone_bootup(zlogp, zargp->bootbuf, zstate);
1845                         audit_put_record(zlogp, uc, rval, "reboot");
1846                         if (rval != 0) {
1847                                 (void) zone_halt(zlogp, B_FALSE, B_TRUE,
1848                                     zstate);
1849                                 eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1850                         }
1851                         boot_args[0] = '\0';
1852                         break;
1853                 case Z_SHUTDOWN:
1854                         if ((rval = zone_graceful_shutdown(zlogp)) == 0) {
1855                                 wait_shut = B_TRUE;
1856                         }
1857                         break;
1858                 case Z_NOTE_UNINSTALLING:
1859                 case Z_MOUNT: