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, 2003 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>
29 #include <sys/queue.h>
30 #include <sys/capability.h>
32 #include <netinet/in.h>
33 #include <sys/socket.h>
34 #include <arpa/inet.h>
42 /* both sys/queue.h (libsysio require it) and portals/lists.h have definition
43 * of 'LIST_HEAD'. undef it to suppress warnings
47 #include <portals/ptlctl.h> /* needed for parse_dump */
48 #include <procbridge.h>
50 #include "llite_lib.h"
52 unsigned int portal_subsystem_debug = ~0 - (S_PORTALS | S_QSWNAL | S_SOCKNAL |
55 ptl_handle_ni_t tcpnal_ni;
56 struct task_struct *current;
58 /* portals interfaces */
60 struct ldlm_namespace;
64 void *inter_module_get(char *arg)
66 if (!strcmp(arg, "tcpnal_ni"))
68 else if (!strcmp(arg, "ldlm_cli_cancel_unused"))
69 return ldlm_cli_cancel_unused;
70 else if (!strcmp(arg, "ldlm_namespace_cleanup"))
71 return ldlm_namespace_cleanup;
72 else if (!strcmp(arg, "ldlm_replay_locks"))
73 return ldlm_replay_locks;
78 /* XXX move to proper place */
79 char *portals_nid2str(int nal, ptl_nid_t nid, char *str)
85 snprintf(str, PTL_NALFMT_SIZE - 1, "%u:%u.%u.%u.%u",
86 (__u32)(nid >> 32), HIPQUAD(nid));
92 snprintf(str, PTL_NALFMT_SIZE - 1, "%u:%u",
93 (__u32)(nid >> 32), (__u32)nid);
96 snprintf(str, PTL_NALFMT_SIZE - 1, "?%d? %llx",
103 int in_group_p(gid_t gid)
107 if (gid == current->fsgid)
110 for (i = 0; i < current->ngroups; i++) {
111 if (gid == current->groups[i])
118 static void init_capability(int *res)
120 cap_value_t cap_types[] = {
129 /* following are linux specific, we could simply
130 * remove them I think */
133 CAP_NET_BIND_SERVICE,
154 cap_flag_value_t capval;
159 syscap = cap_get_proc();
161 printf("Liblustre: Warning: failed to get system capability, "
166 for (i = 0; i < sizeof(cap_types)/sizeof(cap_t); i++) {
167 LASSERT(cap_types[i] < 32);
168 if (!cap_get_flag(syscap, cap_types[i],
169 CAP_EFFECTIVE, &capval)) {
170 if (capval == CAP_SET) {
171 *res |= 1 << cap_types[i];
177 static int init_current(char *comm)
179 current = malloc(sizeof(*current));
181 CERROR("Not enough memory\n");
184 current->fs = ¤t->__fs;
185 current->fs->umask = umask(0777);
186 umask(current->fs->umask);
188 strncpy(current->comm, comm, sizeof(current->comm));
189 current->pid = getpid();
190 current->fsuid = geteuid();
191 current->fsgid = getegid();
192 memset(¤t->pending, 0, sizeof(current->pending));
194 current->max_groups = sysconf(_SC_NGROUPS_MAX);
195 current->groups = malloc(sizeof(gid_t) * current->max_groups);
196 if (!current->groups) {
197 CERROR("Not enough memory\n");
200 current->ngroups = getgroups(current->max_groups, current->groqps);
201 if (current->ngroups < 0) {
202 perror("Error getgroups");
206 init_capability(¤t->cap_effective);
212 void generate_random_uuid(unsigned char uuid_out[16])
214 int *arr = (int*)uuid_out;
217 for (i = 0; i < sizeof(uuid_out)/sizeof(int); i++)
221 ptl_nid_t tcpnal_mynid;
223 int init_lib_portals()
229 rc = PtlInit(&max_interfaces);
231 CERROR("PtlInit failed: %d\n", rc);
238 libcfs_nal_cmd(struct portals_cfg *pcfg)
240 /* handle portals command if we want */
244 extern int class_handle_ioctl(unsigned int cmd, unsigned long arg);
246 int lib_ioctl_nalcmd(int dev_id, unsigned int opc, void * ptr)
248 struct portal_ioctl_data *ptldata;
250 if (opc == IOC_PORTAL_NAL_CMD) {
251 ptldata = (struct portal_ioctl_data *) ptr;
253 if (ptldata->ioc_nal_cmd == NAL_CMD_REGISTER_MYNID) {
254 tcpnal_mynid = ptldata->ioc_nid;
255 printf("mynid: %u.%u.%u.%u\n",
256 (unsigned)(tcpnal_mynid>>24) & 0xFF,
257 (unsigned)(tcpnal_mynid>>16) & 0xFF,
258 (unsigned)(tcpnal_mynid>>8) & 0xFF,
259 (unsigned)(tcpnal_mynid) & 0xFF);
266 int lib_ioctl(int dev_id, unsigned int opc, void * ptr)
270 if (dev_id == OBD_DEV_ID) {
271 struct obd_ioctl_data *ioc = ptr;
274 ioc->ioc_plen1 = ioc->ioc_inllen1;
275 ioc->ioc_pbuf1 = ioc->ioc_bulk;
278 rc = class_handle_ioctl(opc, (unsigned long)ptr);
280 printf ("proccssing ioctl cmd: %x, rc %d\n", opc, rc);
288 int lllib_init(char *dumpfile)
291 /* this parse only get my nid from config file
292 * before initialize portals
294 if (parse_dump(dumpfile, lib_ioctl_nalcmd))
297 /* XXX need setup mynid before tcpnal initialize */
298 tcpnal_mynid = ((uint64_t)getpid() << 32) | time(0);
299 printf("LibLustre: TCPNAL NID: %016llx\n", tcpnal_mynid);
302 if (init_current("dummy") ||
304 init_lib_portals() ||
311 if (!g_zconf && parse_dump(dumpfile, lib_ioctl))
314 return _sysio_fssw_register("llite", &llu_fssw_ops);
318 static void llu_check_request()
320 liblustre_wait_event(0);
324 int liblustre_process_log(struct config_llog_instance *cfg, int allow_recov)
326 struct lustre_cfg lcfg;
327 char *peer = "MDS_PEER_UUID";
328 struct obd_device *obd;
329 struct lustre_handle mdc_conn = {0, };
330 struct obd_export *exp;
331 char *name = "mdc_dev";
333 struct obd_uuid mdc_uuid;
334 struct llog_ctxt *ctxt;
336 int nal, err, rc = 0;
339 generate_random_uuid(uuid);
340 class_uuid_unparse(uuid, &mdc_uuid);
342 if (ptl_parse_nid(&nid, g_zconf_mdsnid)) {
343 CERROR("Can't parse NID %s\n", g_zconf_mdsnid);
347 nal = ptl_name2nal("tcp");
349 CERROR("Can't parse NAL tcp\n");
352 LCFG_INIT(lcfg, LCFG_ADD_UUID, NULL);
354 lcfg.lcfg_inllen1 = strlen(peer) + 1;
355 lcfg.lcfg_inlbuf1 = peer;
357 err = class_process_config(&lcfg);
361 LCFG_INIT(lcfg, LCFG_ATTACH, name);
362 lcfg.lcfg_inlbuf1 = "mdc";
363 lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
364 lcfg.lcfg_inlbuf2 = mdc_uuid.uuid;
365 lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
366 err = class_process_config(&lcfg);
368 GOTO(out_del_uuid, err);
370 LCFG_INIT(lcfg, LCFG_SETUP, name);
371 lcfg.lcfg_inlbuf1 = g_zconf_mdsname;
372 lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
373 lcfg.lcfg_inlbuf2 = peer;
374 lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
375 err = class_process_config(&lcfg);
377 GOTO(out_detach, err);
379 obd = class_name2obd(name);
381 GOTO(out_cleanup, err = -EINVAL);
383 /* Disable initial recovery on this import */
384 err = obd_set_info(obd->obd_self_export,
385 strlen("initial_recov"), "initial_recov",
386 sizeof(allow_recov), &allow_recov);
388 err = obd_connect(&mdc_conn, obd, &mdc_uuid);
390 CERROR("cannot connect to %s: rc = %d\n",
391 g_zconf_mdsname, err);
392 GOTO(out_cleanup, err);
395 exp = class_conn2export(&mdc_conn);
397 ctxt = exp->exp_obd->obd_llog_ctxt[LLOG_CONFIG_REPL_CTXT];
398 rc = class_config_parse_llog(ctxt, g_zconf_profile, cfg);
400 CERROR("class_config_parse_llog failed: rc = %d\n", rc);
403 err = obd_disconnect(exp, 0);
406 LCFG_INIT(lcfg, LCFG_CLEANUP, name);
407 err = class_process_config(&lcfg);
412 LCFG_INIT(lcfg, LCFG_DETACH, name);
413 err = class_process_config(&lcfg);
418 LCFG_INIT(lcfg, LCFG_DEL_UUID, name);
419 lcfg.lcfg_inllen1 = strlen(peer) + 1;
420 lcfg.lcfg_inlbuf1 = peer;
421 err = class_process_config(&lcfg);
430 /* parse host:/mdsname/profile string */
431 int ll_parse_mount_target(const char *target, char **mdsnid,
432 char **mdsname, char **profile)
434 static char buf[256];
438 strncpy(buf, target, 255);
440 if ((s = strchr(buf, ':'))) {
447 if ((s = strchr(*mdsname, '/'))) {
458 #define ENV_LUSTRE_MNTPNT "LIBLUSTRE_MOUNT_POINT"
459 #define ENV_LUSTRE_MNTTGT "LIBLUSTRE_MOUNT_TARGET"
460 #define ENV_LUSTRE_TIMEOUT "LIBLUSTRE_TIMEOUT"
461 #define ENV_LUSTRE_DUMPFILE "LIBLUSTRE_DUMPFILE"
463 extern int _sysio_native_init();
465 extern unsigned int obd_timeout;
467 /* global variables */
468 int g_zconf = 0; /* zeroconf or dumpfile */
469 char *g_zconf_mdsname = NULL; /* mdsname, for zeroconf */
470 char *g_zconf_mdsnid = NULL; /* mdsnid, for zeroconf */
471 char *g_zconf_profile = NULL; /* profile, for zeroconf */
474 void __liblustre_setup_(void)
476 char *lustre_path = NULL;
478 char *timeout = NULL;
479 char *dumpfile = NULL;
480 char *root_driver = "native";
481 char *lustre_driver = "llite";
482 char *root_path = "/";
483 unsigned mntflgs = 0;
487 /* consider tha case of starting multiple liblustre instances
488 * at a same time on single node.
490 srand(time(NULL) + getpid());
492 lustre_path = getenv(ENV_LUSTRE_MNTPNT);
494 lustre_path = "/mnt/lustre";
497 target = getenv(ENV_LUSTRE_MNTTGT);
499 dumpfile = getenv(ENV_LUSTRE_DUMPFILE);
501 CERROR("Neither mount target, nor dumpfile\n");
505 printf("LibLustre: mount point %s, dumpfile %s\n",
506 lustre_path, dumpfile);
508 if (ll_parse_mount_target(target,
512 CERROR("mal-formed target %s \n", target);
516 printf("LibLustre: mount point %s, target %s\n",
517 lustre_path, target);
520 timeout = getenv(ENV_LUSTRE_TIMEOUT);
522 obd_timeout = (unsigned int) atoi(timeout);
523 printf("LibLustre: set obd timeout as %u seconds\n",
527 if (_sysio_init() != 0) {
528 perror("init sysio");
532 /* cygwin don't need native driver */
534 _sysio_native_init();
537 err = _sysio_mount_root(root_path, root_driver, mntflgs, NULL);
545 portal_subsystem_debug = 0;
547 err = lllib_init(dumpfile);
549 perror("init llite driver");
553 err = mount("/", lustre_path, lustre_driver, mntflgs, NULL);
556 perror(lustre_driver);
561 __sysio_hook_sys_enter = llu_check_request;
562 __sysio_hook_sys_leave = NULL;
566 void __liblustre_cleanup_(void)