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:
|