1 /*****************************************************************************
2 *
3 * Copyright (C) 2002-2007 The Regents of the University of California.
4 * Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
5 * Produced at Lawrence Livermore National Laboratory.
6 * Written by Mark Grondona <mgrondona@llnl.gov>.
7 *
8 * UCRL-CODE-235358
9 *
10 * This file is part of chaos-spankings, a set of spank plugins for SLURM.
11 *
12 * This is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 ****************************************************************************
25 * An option --core=<arg> is added for the srun command.
26 * Valid arguments are normal, light, lcb and list.
27 ****************************************************************************/
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
34 #include <unistd.h>
35
36 #include <slurm/spank.h>
37
38 #define CORE_INVALID -1
39 #define CORE_NORMAL 0
40 #define CORE_LIGHT 1 /* Default lightweight corefile from liblwcf */
41 #define CORE_LCB 2 /* PTOOLS Lightweight Corefile Browser (LCB) compliant*/
42 #define CORE_LIST 3 /* List core format types to stdout and exit */
43 #define LIB_LIGHT "liblwcf-preload.so"
44
45 struct core_format_info {
46 int type;
47 const char *name;
48 const char *descr;
49 };
50
51 /*
52 * Supported types for core=%s
53 */
54 struct core_format_info core_types[] = {
55 { CORE_NORMAL,
56 "normal",
57 "Default full corefile (do nothing)"
58 },
59 { CORE_LIGHT,
60 "light",
61 "liblwcf default lightweight corefile format"
62 },
63 { CORE_LCB,
64 "lcb",
65 "liblwcf Lightweight Corefile Browser compliant"
66 },
67 { CORE_LIST,
68 "list",
69 "list valid core format types"
70 },
71 { CORE_INVALID,
72 NULL,
73 "Invalid format"
74 }
75 };
76
77 /*
78 * All spank plugins must define this macro for the Slurm plugin loader.
79 */
80 SPANK_PLUGIN(core, 1)
81
82 static int core_mode = CORE_NORMAL;
83
84 static int _opt_process (int val, const char *optarg, int remote);
85
86 struct spank_option spank_option_array[] =
87 {
88 { "core", "format", "Core file format", 1, 0,
89 (spank_opt_cb_f) _opt_process },
90 SPANK_OPTIONS_TABLE_END
91 };
92
_print_valid_core_types(void)93 static void _print_valid_core_types (void)
94 {
95 struct core_format_info *ci;
96
97 info ("Valid corefile format types:");
98 for (ci = core_types; ci && ci->name; ci++) {
99 if ((ci->type == CORE_LIGHT) ||
100 (ci->type == CORE_LCB)) {
101 struct stat buf;
102 if ((stat("/lib/" LIB_LIGHT, &buf) < 0) &&
103 (stat("/usr/lib/" LIB_LIGHT, &buf) < 0) &&
104 (stat("/usr/local/lib/" LIB_LIGHT, &buf) < 0))
105 continue;
106 }
107 if (ci->type != CORE_LIST)
108 info(" %-8s -- %s", ci->name, ci->descr);
109 }
110 return;
111 }
112
_opt_process(int val,const char * optarg,int remote)113 static int _opt_process (int val, const char *optarg, int remote)
114 {
115 int i;
116 struct core_format_info *ci;
117
118 for (ci = core_types; ci && ci->name; ci++) {
119 if (strcasecmp(optarg, ci->name))
120 continue;
121 core_mode = ci->type;
122 if (core_mode == CORE_LIST) {
123 _print_valid_core_types();
124 exit(0);
125 }
126 return ESPANK_SUCCESS;
127 }
128
129 slurm_error("Invalid core option: %s", optarg);
130 exit(-1);
131 }
132
slurm_spank_init(spank_t sp,int ac,char ** av)133 int slurm_spank_init(spank_t sp, int ac, char **av)
134 {
135 spank_context_t context;
136 int i, j, rc = ESPANK_SUCCESS;
137 char *core_env;
138
139 for (i=0; spank_option_array[i].name; i++) {
140 j = spank_option_register(sp, &spank_option_array[i]);
141 if (j != ESPANK_SUCCESS) {
142 slurm_error("Could not register Spank option %s",
143 spank_option_array[i].name);
144 rc = j;
145 }
146 }
147
148 context = spank_context();
149 if (context == S_CTX_LOCAL) {
150 core_env = getenv("SLURM_CORE_FORMAT");
151 if (core_env)
152 rc = _opt_process(0, core_env, 0);
153 }
154
155 return rc;
156 }
157
slurm_spank_init_post_opt(spank_t sp,int ac,char ** av)158 int slurm_spank_init_post_opt (spank_t sp, int ac, char **av)
159 {
160 spank_context_t context;
161 int rc = ESPANK_SUCCESS;
162
163 context = spank_context();
164 if (context != S_CTX_LOCAL)
165 return rc;
166
167 switch (core_mode) {
168 case CORE_NORMAL:
169 case CORE_INVALID:
170 break;
171 case CORE_LCB:
172 setenvfs("LWCF_CORE_FORMAT=LCB");
173 case CORE_LIGHT:
174 setenvfs("LD_PRELOAD=" LIB_LIGHT);
175 break;
176 }
177
178 return rc;
179 }
180