1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Lustre Light common routines
6 * Copyright (c) 2002-2004 Cluster File Systems, Inc.
8 * This file is part of Lustre, http://www.lustre.org.
10 * Lustre is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General Public
12 * License as published by the Free Software Foundation.
14 * Lustre is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Lustre; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <sys/types.h>
30 #include <sys/queue.h>
43 /* both sys/queue.h (libsysio require it) and portals/lists.h have definition
44 * of 'LIST_HEAD'. undef it to suppress warnings
47 #include <lnet/lnetctl.h> /* needed for parse_dump */
50 #include "llite_lib.h"
52 static int lllib_init(void)
54 if (liblustre_init_current("liblustre") ||
65 return _sysio_fssw_register("lustre", &llu_fssw_ops);
68 int liblustre_process_log(struct config_llog_instance *cfg,
69 char *mgsnid, char *profile,
72 struct lustre_cfg_bufs bufs;
73 struct lustre_cfg *lcfg;
74 char *peer = "MGS_UUID";
75 struct obd_device *obd;
76 struct lustre_handle mgc_conn = {0, };
77 struct obd_export *exp;
78 char *name = "mgc_dev";
80 struct obd_uuid mgc_uuid;
81 struct llog_ctxt *ctxt;
85 struct obd_connect_data *ocd = NULL;
88 ll_generate_random_uuid(uuid);
89 class_uuid_unparse(uuid, &mgc_uuid);
91 nid = libcfs_str2nid(mgsnid);
92 if (nid == LNET_NID_ANY) {
93 CERROR("Can't parse NID %s\n", mgsnid);
97 lustre_cfg_bufs_reset(&bufs, NULL);
98 lustre_cfg_bufs_set_string(&bufs, 1, peer);
99 lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs);
100 lcfg->lcfg_nid = nid;
101 rc = class_process_config(lcfg);
102 lustre_cfg_free(lcfg);
106 lustre_cfg_bufs_reset(&bufs, name);
107 lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MGC_NAME);
108 lustre_cfg_bufs_set_string(&bufs, 2, mgc_uuid.uuid);
109 lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs);
110 rc = class_process_config(lcfg);
111 lustre_cfg_free(lcfg);
113 GOTO(out_del_uuid, rc);
115 lustre_cfg_bufs_reset(&bufs, name);
116 lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MGS_OBDNAME);
117 lustre_cfg_bufs_set_string(&bufs, 2, peer);
118 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
119 rc = class_process_config(lcfg);
120 lustre_cfg_free(lcfg);
122 GOTO(out_detach, rc);
124 while ((mdsnid = strsep(&mgsnid, ","))) {
125 nid = libcfs_str2nid(mdsnid);
126 lustre_cfg_bufs_reset(&bufs, NULL);
127 lustre_cfg_bufs_set_string(&bufs, 1, libcfs_nid2str(nid));
128 lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs);
129 lcfg->lcfg_nid = nid;
130 rc = class_process_config(lcfg);
131 lustre_cfg_free(lcfg);
133 CERROR("Add uuid for %s failed %d\n",
134 libcfs_nid2str(nid), rc);
138 lustre_cfg_bufs_reset(&bufs, name);
139 lustre_cfg_bufs_set_string(&bufs, 1, libcfs_nid2str(nid));
140 lcfg = lustre_cfg_new(LCFG_ADD_CONN, &bufs);
141 lcfg->lcfg_nid = nid;
142 rc = class_process_config(lcfg);
143 lustre_cfg_free(lcfg);
145 CERROR("Add conn for %s failed %d\n",
146 libcfs_nid2str(nid), rc);
151 obd = class_name2obd(name);
153 GOTO(out_cleanup, rc = -EINVAL);
155 OBD_ALLOC(ocd, sizeof(*ocd));
157 GOTO(out_cleanup, rc = -ENOMEM);
159 ocd->ocd_connect_flags = OBD_CONNECT_VERSION;
160 ocd->ocd_version = LUSTRE_VERSION_CODE;
162 rc = obd_connect(NULL, &mgc_conn, obd, &mgc_uuid, ocd);
164 CERROR("cannot connect to %s at %s: rc = %d\n",
165 LUSTRE_MGS_OBDNAME, mgsnid, rc);
166 GOTO(out_cleanup, rc);
169 exp = class_conn2export(&mgc_conn);
171 ctxt = exp->exp_obd->obd_llog_ctxt[LLOG_CONFIG_REPL_CTXT];
172 cfg->cfg_flags |= CFG_F_COMPAT146;
173 rc = class_config_parse_llog(ctxt, profile, cfg);
175 CERROR("class_config_parse_llog failed: rc = %d\n", rc);
178 /* We don't so much care about errors in cleaning up the config llog
179 * connection, as we have already read the config by this point. */
180 err = obd_disconnect(exp);
182 CERROR("obd_disconnect failed: rc = %d\n", err);
186 OBD_FREE(ocd, sizeof(*ocd));
188 lustre_cfg_bufs_reset(&bufs, name);
189 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
190 err = class_process_config(lcfg);
191 lustre_cfg_free(lcfg);
193 CERROR("md_cleanup failed: rc = %d\n", err);
196 lustre_cfg_bufs_reset(&bufs, name);
197 lcfg = lustre_cfg_new(LCFG_DETACH, &bufs);
198 err = class_process_config(lcfg);
199 lustre_cfg_free(lcfg);
201 CERROR("md_detach failed: rc = %d\n", err);
204 lustre_cfg_bufs_reset(&bufs, name);
205 lustre_cfg_bufs_set_string(&bufs, 1, peer);
206 lcfg = lustre_cfg_new(LCFG_DEL_UUID, &bufs);
207 err = class_process_config(lcfg);
209 CERROR("del MDC UUID failed: rc = %d\n", err);
210 lustre_cfg_free(lcfg);
216 /* parse host:/fsname string */
217 int ll_parse_mount_target(const char *target, char **mgsnid,
220 static char buf[256];
224 strncpy(buf, target, 255);
226 if ((s = strchr(buf, ':'))) {
232 sprintf(s + strlen(s), "-client");
242 * early liblustre init
243 * called from C startup in catamount apps, before main()
245 * The following is a skeleton sysio startup sequence,
246 * as implemented in C startup (skipping error handling).
247 * In this framework none of these calls need be made here
248 * or in the apps themselves. The NAMESPACE_STRING specifying
249 * the initial set of fs ops (creates, mounts, etc.) is passed
250 * as an environment variable.
253 * _sysio_incore_init();
254 * _sysio_native_init();
255 * _sysio_lustre_init();
256 * _sysio_boot(NAMESPACE_STRING);
258 * the name _sysio_lustre_init() follows the naming convention
259 * established in other fs drivers from libsysio:
260 * _sysio_incore_init(), _sysio_native_init()
262 * _sysio_lustre_init() must be called before _sysio_boot()
263 * to enable libsysio's processing of namespace init strings containing
264 * lustre filesystem operations
266 int _sysio_lustre_init(void)
271 extern void __liblustre_cleanup_(void);
274 liblustre_init_random();
278 perror("init llite driver");
282 envstr = getenv("LIBLUSTRE_TIMEOUT");
283 if (envstr != NULL) {
284 obd_timeout = (unsigned int)strtol(envstr, NULL, 0);
285 printf("LibLustre: obd timeout=%u seconds\n",
289 /* debug peer on timeout? */
290 envstr = getenv("LIBLUSTRE_DEBUG_PEER_ON_TIMEOUT");
291 if (envstr != NULL) {
292 obd_debug_peer_on_timeout =
293 (unsigned int)strtol(envstr, NULL, 0);
294 printf("LibLustre: debug peer on timeout=%d\n",
295 obd_debug_peer_on_timeout ? 0 : 1);
299 (void)atexit(__liblustre_cleanup_);
304 extern int _sysio_native_init();
306 char *lustre_path = NULL;
308 void __liblustre_setup_(void)
311 char *lustre_driver = "lustre";
312 unsigned mntflgs = 0;
315 lustre_path = getenv("LIBLUSTRE_MOUNT_POINT");
317 lustre_path = "/mnt/lustre";
321 target = getenv("LIBLUSTRE_MOUNT_TARGET");
323 printf("LibLustre: no mount target specified\n");
327 CDEBUG(D_CONFIG, "LibLustre: mount point %s, target %s\n",
328 lustre_path, target);
331 /* initialize libsysio & mount rootfs */
333 perror("init sysio");
336 _sysio_native_init();
338 err = _sysio_mount_root("/", "native", mntflgs, NULL);
340 fprintf(stderr, "sysio mount failed: %s\n", strerror(errno));
344 if (_sysio_lustre_init())
346 #endif /* INIT_SYSIO */
348 err = mount(target, lustre_path, lustre_driver, mntflgs, NULL);
350 fprintf(stderr, "Lustre mount failed: %s\n", strerror(errno));
355 void __liblustre_cleanup_(void)
358 /* guard against being called multiple times */
359 static int cleaned = 0;
366 /* user app might chdir to a lustre directory, and leave busy pnode
367 * during finaly libsysio cleanup. here we chdir back to "/".
368 * but it can't fix the situation that liblustre is mounted
375 /* we can't call umount here, because libsysio will not cleanup
376 * opening files for us. _sysio_shutdown() will cleanup fds at
377 * first but which will also close the sockets we need for umount
378 * liblutre. this dilema lead to another hack in
379 * libsysio/src/file_hack.c FIXME
383 cleanup_lib_portals();