101 extern int audit_halt_fail(void);
102
103 extern int audit_reboot_setup(void);
104 extern int audit_reboot_success(void);
105 extern int audit_reboot_fail(void);
106
107 static char *cmdname; /* basename(argv[0]), the name of the command */
108
109 typedef struct ctidlist_struct {
110 ctid_t ctid;
111 struct ctidlist_struct *next;
112 } ctidlist_t;
113
114 static ctidlist_t *ctidlist = NULL;
115 static ctid_t startdct = -1;
116
117 #define FMRI_STARTD_CONTRACT \
118 "svc:/system/svc/restarter:default/:properties/restarter/contract"
119
120 #define BEADM_PROG "/usr/sbin/beadm"
121 #define BOOTADM_PROG "/sbin/bootadm"
122 #define ZONEADM_PROG "/usr/sbin/zoneadm"
123
124 /*
125 * The length of FASTBOOT_MOUNTPOINT must be less than MAXPATHLEN.
126 */
127 #define FASTBOOT_MOUNTPOINT "/tmp/.fastboot.root"
128
129 /*
130 * Fast Reboot related variables
131 */
132 static char fastboot_mounted[MAXPATHLEN];
133
134 #if defined(__i386)
135 static grub_boot_args_t fbarg;
136 static grub_boot_args_t *fbarg_used;
137 static int fbarg_entnum = GRUB_ENTRY_DEFAULT;
138 #endif /* __i386 */
139
140 static int validate_ufs_disk(char *, char *);
141 static int validate_zfs_pool(char *, char *);
926 argv[i] = arg;
927 } while (arg != NULL &&
928 ++i != sizeof (argv) / sizeof (argv[0]));
929
930 va_end(vp);
931
932 (void) execve(path, (char * const *)argv, NULL);
933 (void) fprintf(stderr, gettext("Cannot execute %s: %s\n"),
934 path, strerror(errno));
935 exit(-1);
936 } else {
937 if (waitpid(pid, &st, 0) == pid &&
938 !WIFSIGNALED(st) && WIFEXITED(st))
939 st = WEXITSTATUS(st);
940 else
941 st = -1;
942 }
943 return (st);
944 }
945
946 /*
947 * Mount the specified BE.
948 *
949 * Upon success returns zero and copies bename string to mountpoint[]
950 */
951 static int
952 fastboot_bename(const char *bename, char *mountpoint, size_t mpsz)
953 {
954 int rc;
955
956 /*
957 * Attempt to unmount the BE first in case it's already mounted
958 * elsewhere.
959 */
960 (void) halt_exec(BEADM_PROG, "umount", bename, NULL);
961
962 if ((rc = halt_exec(BEADM_PROG, "mount", bename, FASTBOOT_MOUNTPOINT,
963 NULL)) != 0)
964 (void) fprintf(stderr,
965 gettext("%s: Unable to mount BE \"%s\" at %s\n"),
1041 if (*is_dryrun)
1042 return (rc);
1043
1044 #if defined(__i386)
1045 /* Read boot args from GRUB menu */
1046 if ((bootargs_buf[0] == 0 || isdigit(bootargs_buf[0])) &&
1047 bename == NULL) {
1048 /*
1049 * If no boot arguments are given, or a GRUB menu entry
1050 * number is provided, process the GRUB menu.
1051 */
1052 int entnum;
1053 if (bootargs_buf[0] == 0)
1054 entnum = GRUB_ENTRY_DEFAULT;
1055 else {
1056 errno = 0;
1057 entnum = strtoul(bootargs_buf, NULL, 10);
1058 rc = errno;
1059 }
1060
1061 if (rc == 0 && (rc = grub_get_boot_args(&fbarg, NULL,
1062 entnum)) == 0) {
1063 if (strlcpy(bootargs_buf, fbarg.gba_bootargs,
1064 buf_size) >= buf_size) {
1065 grub_cleanup_boot_args(&fbarg);
1066 bcopy(bootargs_saved, bootargs_buf, buf_size);
1067 rc = E2BIG;
1068 }
1069 }
1070 /* Failed to read GRUB menu, fall back to normal reboot */
1071 if (rc != 0) {
1072 (void) fprintf(stderr,
1073 gettext("%s: Failed to process GRUB menu "
1074 "entry for fast reboot.\n\t%s\n"),
1075 cmdname, grub_strerror(rc));
1076 (void) fprintf(stderr,
1077 gettext("%s: Falling back to regular reboot.\n"),
1078 cmdname);
1079 return (-1);
1080 }
1081 /* No need to process further */
1082 fbarg_used = &fbarg;
1493 gettext("%s: can't turn off auditd\n"), cmdname);
1494 if (needlog)
1495 (void) sleep(5); /* Give syslogd time to record this */
1496 }
1497
1498 (void) signal(SIGHUP, SIG_IGN); /* for remote connections */
1499
1500 /*
1501 * We start to fork a bunch of zoneadms to halt any active zones.
1502 * This will proceed with halt in parallel until we call
1503 * check_zone_haltedness later on.
1504 */
1505 if (zoneid == GLOBAL_ZONEID && cmd != A_DUMP) {
1506 need_check_zones = halt_zones();
1507 }
1508
1509 #if defined(__i386)
1510 /* set new default entry in the GRUB entry */
1511 if (fbarg_entnum != GRUB_ENTRY_DEFAULT) {
1512 char buf[32];
1513 (void) snprintf(buf, sizeof (buf), "default=%u", fbarg_entnum);
1514 (void) halt_exec(BOOTADM_PROG, "set-menu", buf, NULL);
1515 }
1516 #endif /* __i386 */
1517
1518 /* if we're dumping, do the archive update here and don't defer it */
1519 if (cmd == A_DUMP && zoneid == GLOBAL_ZONEID && !nosync)
1520 do_archives_update(fast_reboot);
1521
1522 /*
1523 * If we're not forcing a crash dump, mark the system as quiescing for
1524 * smf(5)'s benefit, and idle the init process.
1525 */
1526 if (cmd != A_DUMP) {
1527 if (direct_init(PCDSTOP) == -1) {
1528 /*
1529 * TRANSLATION_NOTE
1530 * Don't translate the word "init"
1531 */
1532 (void) fprintf(stderr,
1533 gettext("%s: can't idle init\n"), cmdname);
1534 goto fail;
|
101 extern int audit_halt_fail(void);
102
103 extern int audit_reboot_setup(void);
104 extern int audit_reboot_success(void);
105 extern int audit_reboot_fail(void);
106
107 static char *cmdname; /* basename(argv[0]), the name of the command */
108
109 typedef struct ctidlist_struct {
110 ctid_t ctid;
111 struct ctidlist_struct *next;
112 } ctidlist_t;
113
114 static ctidlist_t *ctidlist = NULL;
115 static ctid_t startdct = -1;
116
117 #define FMRI_STARTD_CONTRACT \
118 "svc:/system/svc/restarter:default/:properties/restarter/contract"
119
120 #define BEADM_PROG "/usr/sbin/beadm"
121 #define GRUBADM_PROG "/sbin/grubadm"
122 #define ZONEADM_PROG "/usr/sbin/zoneadm"
123
124 /*
125 * The length of FASTBOOT_MOUNTPOINT must be less than MAXPATHLEN.
126 */
127 #define FASTBOOT_MOUNTPOINT "/tmp/.fastboot.root"
128
129 /*
130 * Fast Reboot related variables
131 */
132 static char fastboot_mounted[MAXPATHLEN];
133
134 #if defined(__i386)
135 static grub_boot_args_t fbarg;
136 static grub_boot_args_t *fbarg_used;
137 static int fbarg_entnum = GRUB_ENTRY_DEFAULT;
138 #endif /* __i386 */
139
140 static int validate_ufs_disk(char *, char *);
141 static int validate_zfs_pool(char *, char *);
926 argv[i] = arg;
927 } while (arg != NULL &&
928 ++i != sizeof (argv) / sizeof (argv[0]));
929
930 va_end(vp);
931
932 (void) execve(path, (char * const *)argv, NULL);
933 (void) fprintf(stderr, gettext("Cannot execute %s: %s\n"),
934 path, strerror(errno));
935 exit(-1);
936 } else {
937 if (waitpid(pid, &st, 0) == pid &&
938 !WIFSIGNALED(st) && WIFEXITED(st))
939 st = WEXITSTATUS(st);
940 else
941 st = -1;
942 }
943 return (st);
944 }
945
946 static int
947 exec_cmd(char * invoke, char * output)
948 {
949 FILE * cmd = popen(invoke, "r");
950 if (! cmd)
951 return 0;
952 fgets(output, 512, cmd);
953 if (! *output) {
954 pclose(cmd);
955 return 0;
956 }
957 output[strlen(output) - 2] = '\0';
958 pclose(cmd);
959 return 1;
960 }
961
962 /*
963 * Mount the specified BE.
964 *
965 * Upon success returns zero and copies bename string to mountpoint[]
966 */
967 static int
968 fastboot_bename(const char *bename, char *mountpoint, size_t mpsz)
969 {
970 int rc;
971
972 /*
973 * Attempt to unmount the BE first in case it's already mounted
974 * elsewhere.
975 */
976 (void) halt_exec(BEADM_PROG, "umount", bename, NULL);
977
978 if ((rc = halt_exec(BEADM_PROG, "mount", bename, FASTBOOT_MOUNTPOINT,
979 NULL)) != 0)
980 (void) fprintf(stderr,
981 gettext("%s: Unable to mount BE \"%s\" at %s\n"),
1057 if (*is_dryrun)
1058 return (rc);
1059
1060 #if defined(__i386)
1061 /* Read boot args from GRUB menu */
1062 if ((bootargs_buf[0] == 0 || isdigit(bootargs_buf[0])) &&
1063 bename == NULL) {
1064 /*
1065 * If no boot arguments are given, or a GRUB menu entry
1066 * number is provided, process the GRUB menu.
1067 */
1068 int entnum;
1069 if (bootargs_buf[0] == 0)
1070 entnum = GRUB_ENTRY_DEFAULT;
1071 else {
1072 errno = 0;
1073 entnum = strtoul(bootargs_buf, NULL, 10);
1074 rc = errno;
1075 }
1076
1077 if (rc == 0 && (rc = exec_cmd("/sbin/grubadm --number -1 --get-opts",
1078 fbarg.gba_bootargs)) == 0) {
1079 if (strlcpy(bootargs_buf, fbarg.gba_bootargs,
1080 buf_size) >= buf_size) {
1081 grub_cleanup_boot_args(&fbarg);
1082 bcopy(bootargs_saved, bootargs_buf, buf_size);
1083 rc = E2BIG;
1084 }
1085 }
1086 /* Failed to read GRUB menu, fall back to normal reboot */
1087 if (rc != 0) {
1088 (void) fprintf(stderr,
1089 gettext("%s: Failed to process GRUB menu "
1090 "entry for fast reboot.\n\t%s\n"),
1091 cmdname, grub_strerror(rc));
1092 (void) fprintf(stderr,
1093 gettext("%s: Falling back to regular reboot.\n"),
1094 cmdname);
1095 return (-1);
1096 }
1097 /* No need to process further */
1098 fbarg_used = &fbarg;
1509 gettext("%s: can't turn off auditd\n"), cmdname);
1510 if (needlog)
1511 (void) sleep(5); /* Give syslogd time to record this */
1512 }
1513
1514 (void) signal(SIGHUP, SIG_IGN); /* for remote connections */
1515
1516 /*
1517 * We start to fork a bunch of zoneadms to halt any active zones.
1518 * This will proceed with halt in parallel until we call
1519 * check_zone_haltedness later on.
1520 */
1521 if (zoneid == GLOBAL_ZONEID && cmd != A_DUMP) {
1522 need_check_zones = halt_zones();
1523 }
1524
1525 #if defined(__i386)
1526 /* set new default entry in the GRUB entry */
1527 if (fbarg_entnum != GRUB_ENTRY_DEFAULT) {
1528 char buf[32];
1529 (void) snprintf(buf, sizeof (buf), "--set-default %u", fbarg_entnum);
1530 (void) halt_exec(GRUBADM_PROG, " ", buf, NULL);
1531 }
1532 #endif /* __i386 */
1533
1534 /* if we're dumping, do the archive update here and don't defer it */
1535 if (cmd == A_DUMP && zoneid == GLOBAL_ZONEID && !nosync)
1536 do_archives_update(fast_reboot);
1537
1538 /*
1539 * If we're not forcing a crash dump, mark the system as quiescing for
1540 * smf(5)'s benefit, and idle the init process.
1541 */
1542 if (cmd != A_DUMP) {
1543 if (direct_init(PCDSTOP) == -1) {
1544 /*
1545 * TRANSLATION_NOTE
1546 * Don't translate the word "init"
1547 */
1548 (void) fprintf(stderr,
1549 gettext("%s: can't idle init\n"), cmdname);
1550 goto fail;
|