Import version 1.8.3
[s390-tools.git] / ipl_tools / main.c
blob2eaa043a10ace3b800486982d5d9bcbcd804936f
1 /*
2 * Copyright IBM Corp 2008
3 * Author: Hans-Joachim Picht <hans@linux.vnet.ibm.com>
5 * Linux for System z shutdown action
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 #include <ctype.h>
18 #include <getopt.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <errno.h>
23 #include <string.h>
24 #include <fcntl.h>
25 #include <sys/stat.h>
26 #include <sys/wait.h>
27 #include <sys/types.h>
28 #include <signal.h>
29 #include <syslog.h>
30 #include <pthread.h>
31 #include <setjmp.h>
32 #include "chreipl.h"
34 int use_ccw = 1; /* default is a ccw device */
35 char loadparm[9]; /* the entry in the boot menu */
36 int loadparm_set;
37 int verbose; /* default: don't be verbose */
38 int bootprog; /* default bootprog value is 0 */
39 int bootprog_set;
40 char wwpn[20]; /* 18 character +0x" */
41 int wwpn_set;
42 char lun[20]; /* 18 character +0x" */
43 int lun_set;
44 char devno[9]; /* device number e.g. 0.0.4711 */
45 int devno_set;
46 char device[9]; /* the device itself, e.g. sda1 */
47 char partition[15]; /* partition, e.g. /dev/dasda1 */
48 int partition_set;
49 char devparent[9]; /* the device a partion belongs to. e.g. dasda */
50 char saction[8]; /* the shutdown action */
51 char name[256]; /* program name */
52 int action; /* either CCW, FCP or NODE */
55 * "main" function for the lsreipl related stuff
57 int lsreipl(int argc, char *argv[])
59 int rc;
60 char bootprog[1024], lba[1024], val[9];
62 /* parse the command line options in getop.c */
63 parse_lsreipl_options(argc, argv);
65 rc = get_reipl_type();
66 if (rc == 0) {
67 printf("Re-IPL type: fcp\n");
68 rc = strrd(wwpn, "/sys/firmware/reipl/fcp/wwpn");
69 if (rc != 0)
70 exit(1);
71 rc = strrd(lun, "/sys/firmware/reipl/fcp/lun");
72 if (rc != 0)
73 exit(1);
74 rc = strrd(devno, "/sys/firmware/reipl/fcp/device");
75 if (rc != 0)
76 exit(1);
77 rc = strrd(bootprog, "/sys/firmware/reipl/fcp/bootprog");
78 if (rc != 0)
79 exit(1);
80 rc = strrd(lba, "/sys/firmware/reipl/fcp/br_lba");
81 if (rc != 0)
82 exit(1);
83 if (strlen(wwpn) > 0)
84 printf("WWPN: %s\n", wwpn);
85 if (strlen(lun) > 0)
86 printf("LUN: %s\n", lun);
87 if (strlen(devno) > 0)
88 printf("Device: %s\n", devno);
89 if (strlen(bootprog) > 0)
90 printf("bootprog: %s\n", bootprog);
91 if (strlen(lba) > 0)
92 printf("br_lba: %s\n", lba);
94 if (rc == 1) {
95 printf("Re-IPL type: ccw\n");
96 rc = strrd(devno, "/sys/firmware/reipl/ccw/device");
97 if (rc != 0)
98 exit(1);
99 if (strlen(devno) > 0)
100 printf("Device: %s\n", devno);
102 * check if we can read the load parameter (Loadparm)
104 rc = strrd(val, "/sys/firmware/reipl/ccw/loadparm");
105 if (rc != -1)
106 printf("Loadparm: %s\n", val);
107 else
108 printf("Loadparm: \n");
110 return 0;
114 * "main" function for the reipl related stuff
117 int reipl(int argc, char *argv[])
120 int rc, lpval;
121 char path[4096];
123 lpval = 0;
124 /* parse the command line options in getop.c */
125 parse_options(argc, argv);
127 * in case we want to reipl from a ccw device
129 if (use_ccw == 1) {
130 if (action == ACT_NODE) {
131 rc = get_ccw_dev(partition, device);
132 if (rc != 0) {
133 fprintf(stderr, "%s: Cannot find device for "
134 "partition: %s\n", name, partition);
135 exit(1);
137 rc = get_ccw_devno(device, devno);
138 if (rc != 0) {
139 fprintf(stderr, "%s: Unable to lookup device"
140 " number for device %s\n", name,
141 device);
142 exit(1);
145 if (isccwdev(devno) != 0) {
146 fprintf(stderr, "%s: Unable to find a valid ccw"
147 " device number\n", name);
148 exit(1);
150 rc = strwrt(devno, "/sys/firmware/reipl/ccw/device");
151 if (rc != 0)
152 fprintf(stderr, "%s: Failed to set ccw device "
153 "number\n", name);
154 rc = strwrt("ccw", "/sys/firmware/reipl/reipl_type");
155 if (rc != 0)
156 fprintf(stderr, "%s: Failed to set reipl type "
157 "to ccw\n", name);
158 printf("Settings changed to: %s\n", devno);
159 printf("Re-IPL type: ccw\n");
160 if (strlen(loadparm) != 0) {
161 rc = strwrt(loadparm,
162 "/sys/firmware/reipl/ccw/loadparm");
163 } else {
164 rc = ustrwrt("\n",
165 "/sys/firmware/reipl/ccw/loadparm");
167 if (rc != 0)
168 fprintf(stderr, "%s: Failed to set "
169 "loadparm\n", name);
170 printf("Loadparm: %s\n", loadparm);
173 * in case we reipl from a scsi device
175 if (use_ccw == 0) {
177 * detect the necessary settings based on the device file:
178 * device number, lun and wwpn
180 if (action == ACT_NODE) {
181 /* get the device from the partition */
182 rc = get_fcp_dev(partition, device);
183 if (rc != 0) {
184 fprintf(stderr, "%s Cannot find device for"
185 " partition: %s\n", name, partition);
186 exit(1);
188 if (ispartition(device) != 0) {
189 fprintf(stderr, "%s: %s is not a valid "
190 "partition\n", name, partition);
191 exit(1);
193 if (verbose)
194 printf("device: found %s\n", device);
195 sprintf(path, "/sys/block/%s/device", device);
196 if (verbose)
197 printf("path is %s\n", path);
198 if (chdir(path) != 0) {
199 fprintf(stderr, "%s: Cannot find required"
200 " data related to device %s\n",
201 name, partition);
202 exit(1);
204 rc = get_wwpn(device, wwpn);
205 if (rc != 0) {
206 fprintf(stderr, "%s: Failed to lookup "
207 "WWPN\n", name);
208 exit(1);
210 rc = get_lun(device, lun);
211 if (rc != 0) {
212 fprintf(stderr, "%s: Failed to lookup "
213 "LUN\n", name);
214 exit(1);
216 rc = get_fcp_devno(device, devno);
217 if (rc != 0) {
218 fprintf(stderr, "%s: Cannot find device for "
219 "partition: %s\n", name, partition);
220 exit(1);
222 if (verbose)
223 printf("Device: %s\n", devno);
225 if (isfcpdev(devno) != 0) {
226 fprintf(stderr, "%s: %s is not a valid fcp device"
227 " number.\n", name, devno);
228 exit(1);
230 rc = strwrt(devno, "/sys/firmware/reipl/fcp/device");
231 if (rc != 0) {
232 fprintf(stderr, "%s: Failed to set fcp device "
233 "number\n", name);
234 exit(1);
236 rc = strwrt(wwpn, "/sys/firmware/reipl/fcp/wwpn");
237 if (rc != 0) {
238 fprintf(stderr, "%s: Failed to set WWPN\n", name);
239 exit(1);
241 rc = strwrt(lun, "/sys/firmware/reipl/fcp/lun");
242 if (rc != 0) {
243 fprintf(stderr, "%s: Failed to set fcp LUN\n", name);
244 exit(1);
246 rc = strwrt("fcp", "/sys/firmware/reipl/reipl_type");
247 if (rc != 0) {
248 fprintf(stderr, "%s: Failed to set reipl type to"
249 " fcp\n", name);
250 exit(1);
253 * set the boot record logical block address. Master boot
254 * record. It is always 0 for Linux
256 rc = intwrt(0, "/sys/firmware/reipl/fcp/br_lba");
257 if (rc != 0) {
258 fprintf(stderr, "%s: Failed to set boot record "
259 "logical address to 0\n", name);
260 exit(1);
262 rc = intwrt(bootprog, "/sys/firmware/reipl/fcp/bootprog");
263 if (rc != 0) {
264 fprintf(stderr, "%s: Failed to set "
265 "bootprog\n", name);
266 exit(1);
268 printf("Settings changed to: %s\n", devno);
269 printf("WWPN: %s\n", wwpn);
270 printf("LUN: %s\n", lun);
271 if (bootprog != 0)
272 printf("Bootprog: %d\n", bootprog);
273 printf("Re-IPL type: fcp\n");
275 return 0;
277 /* "main" function for list shutdown actions */
278 int lsshut(int argc, char *argv[])
280 int rc;
281 char tmp[1024];
282 char cmd[1024];
284 parse_lsshut_options(argc, argv);
285 printf("Trigger Action\n");
286 printf("========================\n");
287 if (access("/sys/firmware/shutdown_actions/on_halt", R_OK) == 0) {
288 rc = get_sa(tmp, "on_halt");
289 if (rc != -1) {
290 if (strncmp(tmp, "vmcmd", strlen("vmcmd")) == 0) {
291 rc = strrd(cmd, "/sys/firmware/vmcmd/on_halt");
292 if (rc != 0)
293 exit(1);
294 printf("Halt %s (\"%s\")\n", tmp,
295 cmd);
296 } else
297 printf("Halt %s\n", tmp);
301 if (access("/sys/firmware/shutdown_actions/on_panic", R_OK) == 0) {
302 rc = get_sa(tmp, "on_panic");
303 if (rc != -1) {
304 if (strncmp(tmp, "vmcmd", strlen("vmcmd")) == 0) {
305 rc = strrd(cmd, "/sys/firmware/vmcmd/on_panic");
306 if (rc != 0)
307 exit(1);
308 printf("Panic %s (\"%s\")\n", tmp,
309 cmd);
310 } else
311 printf("Panic %s\n", tmp);
314 if (access("/sys/firmware/shutdown_actions/on_poff", R_OK) == 0) {
315 rc = get_sa(tmp, "on_poff");
316 if (rc != -1) {
317 if (strncmp(tmp, "vmcmd", strlen("vmcmd")) == 0) {
318 rc = strrd(cmd, "/sys/firmware/vmcmd/on_poff");
319 if (rc != 0)
320 exit(1);
321 printf("Power off %s (\"%s\")\n", tmp,
322 cmd);
323 } else
324 printf("Power off %s\n", tmp);
327 if (access("/sys/firmware/shutdown_actions/on_reboot", R_OK) == 0) {
328 rc = get_sa(tmp, "on_reboot");
329 if (rc != -1) {
330 if (strncmp(tmp, "vmcmd", strlen("vmcmd")) == 0) {
331 rc = strrd(cmd, "/sys/firmware/vmcmd/"
332 "on_reboot");
333 if (rc != 0)
334 exit(1);
335 printf("Reboot %s (\"%s\")\n", tmp,
336 cmd);
337 } else
338 printf("Reboot %s\n", tmp);
341 return 0;
344 /* "main" function for shutdown actions */
345 int chshut(int argc, char *argv[])
347 parse_shutdown_options(argc, argv);
348 return 0;
351 int main(int argc, char *argv[])
354 strcpy(name, argv[0]);
355 if (check_for_root() != 0) {
356 fprintf(stderr, "%s: You must be root to perform this "
357 "operation\n", name);
358 exit(1);
360 /* lets see how we are called */
361 if (strstr(argv[0], "chreipl") != NULL) {
362 reipl(argc, argv);
363 return 0;
365 if (strstr(argv[0], "chshut") != NULL) {
366 chshut(argc, argv);
367 return 0;
369 if (strstr(argv[0], "lsreipl") != NULL) {
370 lsreipl(argc, argv);
371 return 0;
373 if (strstr(argv[0], "lsshut") != NULL) {
374 lsshut(argc, argv);
375 return 0;
377 fprintf(stderr, "%s: Dont know how we are called.\n", name);
378 return 1;