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.
31 #include <sys/utsname.h>
32 #include <sys/types.h>
33 #include <sys/queue.h>
35 #include <netinet/in.h>
36 #include <sys/socket.h>
37 #include <arpa/inet.h>
45 /* both sys/queue.h (libsysio require it) and portals/lists.h have definition
46 * of 'LIST_HEAD'. undef it to suppress warnings
50 #include <portals/ptlctl.h> /* needed for parse_dump */
51 #include <procbridge.h>
53 #include "llite_lib.h"
55 unsigned int portal_subsystem_debug = ~0 - (S_PORTALS | S_QSWNAL | S_SOCKNAL |
58 ptl_handle_ni_t tcpnal_ni;
59 struct task_struct *current;
61 /* portals interfaces */
63 struct ldlm_namespace;
67 void *inter_module_get(char *arg)
69 if (!strcmp(arg, "tcpnal_ni"))
71 else if (!strcmp(arg, "ldlm_cli_cancel_unused"))
72 return ldlm_cli_cancel_unused;
73 else if (!strcmp(arg, "ldlm_namespace_cleanup"))
74 return ldlm_namespace_cleanup;
75 else if (!strcmp(arg, "ldlm_replay_locks"))
76 return ldlm_replay_locks;
81 /* XXX move to proper place */
82 char *portals_nid2str(int nal, ptl_nid_t nid, char *str)
88 snprintf(str, PTL_NALFMT_SIZE - 1, "%u:%u.%u.%u.%u",
89 (__u32)(nid >> 32), HIPQUAD(nid));
94 snprintf(str, PTL_NALFMT_SIZE - 1, "%u:%u",
95 (__u32)(nid >> 32), (__u32)nid);
98 snprintf(str, PTL_NALFMT_SIZE - 1, "?%d? %llx",
105 char *portals_id2str(int nal, ptl_process_id_t id, char *str)
111 snprintf(str, PTL_NALFMT_SIZE - 1, "%u:%u.%u.%u.%u,%u",
112 (__u32)(id.nid >> 32), HIPQUAD((id.nid)) , id.pid);
117 snprintf(str, PTL_NALFMT_SIZE - 1, "%u:%u,%u",
118 (__u32)(id.nid >> 32), (__u32)id.nid, id.pid);
121 snprintf(str, PTL_NALFMT_SIZE - 1, "?%d? %llx,%lx",
122 nal, (long long)id.nid, (long)id.pid );
128 * random number generator stuff
130 static int _rand_dev_fd = -1;
132 static int get_ipv4_addr()
134 struct utsname myname;
135 struct hostent *hptr;
138 if (uname(&myname) < 0)
141 hptr = gethostbyname(myname.nodename);
143 hptr->h_addrtype != AF_INET ||
144 *hptr->h_addr_list == NULL) {
145 printf("LibLustre: Warning: fail to get local IPv4 address\n");
149 ip = ntohl(*((int *) *hptr->h_addr_list));
154 static void init_random()
159 _rand_dev_fd = syscall(SYS_open, "/dev/urandom", O_RDONLY);
160 if (_rand_dev_fd >= 0) {
161 if (syscall(SYS_read, _rand_dev_fd, &seed, sizeof(int)) ==
166 syscall(SYS_close, _rand_dev_fd);
170 gettimeofday(&tv, NULL);
171 srand(tv.tv_sec + tv.tv_usec + getpid() + __swab32(get_ipv4_addr()));
174 void get_random_bytes(void *buf, int size)
181 if (_rand_dev_fd >= 0) {
182 if (syscall(SYS_read, _rand_dev_fd, buf, size) == size)
184 syscall(SYS_close, _rand_dev_fd);
192 int in_group_p(gid_t gid)
196 if (gid == current->fsgid)
199 for (i = 0; i < current->ngroups; i++) {
200 if (gid == current->groups[i])
207 static void init_capability(int *res)
210 cap_flag_value_t capval;
215 syscap = cap_get_proc();
217 printf("Liblustre: Warning: failed to get system capability, "
222 for (i = 0; i < sizeof(cap_value_t) * 8; i++) {
223 if (!cap_get_flag(syscap, i, CAP_EFFECTIVE, &capval)) {
224 if (capval == CAP_SET) {
231 static int init_current(char *comm)
233 current = malloc(sizeof(*current));
235 CERROR("Not enough memory\n");
238 current->fs = ¤t->__fs;
239 current->fs->umask = umask(0777);
240 umask(current->fs->umask);
242 strncpy(current->comm, comm, sizeof(current->comm));
243 current->pid = getpid();
244 current->fsuid = geteuid();
245 current->fsgid = getegid();
246 memset(¤t->pending, 0, sizeof(current->pending));
248 current->max_groups = sysconf(_SC_NGROUPS_MAX);
249 current->groups = malloc(sizeof(gid_t) * current->max_groups);
250 if (!current->groups) {
251 CERROR("Not enough memory\n");
254 current->ngroups = getgroups(current->max_groups, current->groups);
255 if (current->ngroups < 0) {
256 perror("Error getgroups");
260 init_capability(¤t->cap_effective);
265 void generate_random_uuid(unsigned char uuid_out[16])
267 get_random_bytes(uuid_out, sizeof(uuid_out));
270 ptl_nid_t tcpnal_mynid;
272 int init_lib_portals()
278 rc = PtlInit(&max_interfaces);
280 CERROR("PtlInit failed: %d\n", rc);
287 libcfs_nal_cmd(struct portals_cfg *pcfg)
289 /* handle portals command if we want */
293 extern int class_handle_ioctl(unsigned int cmd, unsigned long arg);
295 int lib_ioctl_nalcmd(int dev_id, unsigned int opc, void * ptr)
297 struct portal_ioctl_data *ptldata;
299 if (opc == IOC_PORTAL_NAL_CMD) {
300 ptldata = (struct portal_ioctl_data *) ptr;
302 if (ptldata->ioc_nal_cmd == NAL_CMD_REGISTER_MYNID) {
303 tcpnal_mynid = ptldata->ioc_nid;
304 printf("mynid: %u.%u.%u.%u\n",
305 (unsigned)(tcpnal_mynid>>24) & 0xFF,
306 (unsigned)(tcpnal_mynid>>16) & 0xFF,
307 (unsigned)(tcpnal_mynid>>8) & 0xFF,
308 (unsigned)(tcpnal_mynid) & 0xFF);
315 int lib_ioctl(int dev_id, unsigned int opc, void * ptr)
319 if (dev_id == OBD_DEV_ID) {
320 struct obd_ioctl_data *ioc = ptr;
323 ioc->ioc_plen1 = ioc->ioc_inllen1;
324 ioc->ioc_pbuf1 = ioc->ioc_bulk;
327 rc = class_handle_ioctl(opc, (unsigned long)ptr);
329 printf ("proccssing ioctl cmd: %x, rc %d\n", opc, rc);
337 int lllib_init(char *dumpfile)
344 /* this parse only get my nid from config file
345 * before initialize portals
347 if (parse_dump(dumpfile, lib_ioctl_nalcmd))
350 /* need to setup mynid before tcpnal initialization */
351 /* a meaningful nid could help debugging */
352 ip = get_ipv4_addr();
354 get_random_bytes(&ip, sizeof(ip));
355 pid = getpid() & 0xffffffff;
356 tcpnal_mynid = ((uint64_t)ip << 32) | pid;
358 in.s_addr = htonl(ip);
359 printf("LibLustre: TCPNAL NID: %016llx (%s:%u)\n",
360 tcpnal_mynid, inet_ntoa(in), pid);
363 if (init_current("dummy") ||
365 init_lib_portals() ||
372 if (!g_zconf && parse_dump(dumpfile, lib_ioctl))
375 return _sysio_fssw_register("llite", &llu_fssw_ops);
379 static void llu_check_request()
381 liblustre_wait_event(0);
385 int liblustre_process_log(struct config_llog_instance *cfg, int allow_recov)
387 struct lustre_cfg lcfg;
388 char *peer = "MDS_PEER_UUID";
389 struct obd_device *obd;
390 struct lustre_handle mdc_conn = {0, };
391 struct obd_export *exp;
392 char *name = "mdc_dev";
394 struct obd_uuid mdc_uuid;
395 struct llog_ctxt *ctxt;
397 int nal, err, rc = 0;
400 generate_random_uuid(uuid);
401 class_uuid_unparse(uuid, &mdc_uuid);
403 if (ptl_parse_nid(&nid, g_zconf_mdsnid)) {
404 CERROR("Can't parse NID %s\n", g_zconf_mdsnid);
408 nal = ptl_name2nal("tcp");
410 CERROR("Can't parse NAL tcp\n");
413 LCFG_INIT(lcfg, LCFG_ADD_UUID, NULL);
415 lcfg.lcfg_inllen1 = strlen(peer) + 1;
416 lcfg.lcfg_inlbuf1 = peer;
418 err = class_process_config(&lcfg);
422 LCFG_INIT(lcfg, LCFG_ATTACH, name);
423 lcfg.lcfg_inlbuf1 = "mdc";
424 lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
425 lcfg.lcfg_inlbuf2 = mdc_uuid.uuid;
426 lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
427 err = class_process_config(&lcfg);
429 GOTO(out_del_uuid, err);
431 LCFG_INIT(lcfg, LCFG_SETUP, name);
432 lcfg.lcfg_inlbuf1 = g_zconf_mdsname;
433 lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
434 lcfg.lcfg_inlbuf2 = peer;
435 lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
436 err = class_process_config(&lcfg);
438 GOTO(out_detach, err);
440 obd = class_name2obd(name);
442 GOTO(out_cleanup, err = -EINVAL);
444 /* Disable initial recovery on this import */
445 err = obd_set_info(obd->obd_self_export,
446 strlen("initial_recov"), "initial_recov",
447 sizeof(allow_recov), &allow_recov);
449 err = obd_connect(&mdc_conn, obd, &mdc_uuid);
451 CERROR("cannot connect to %s: rc = %d\n",
452 g_zconf_mdsname, err);
453 GOTO(out_cleanup, err);
456 exp = class_conn2export(&mdc_conn);
458 ctxt = exp->exp_obd->obd_llog_ctxt[LLOG_CONFIG_REPL_CTXT];
459 rc = class_config_process_llog(ctxt, g_zconf_profile, &lcfg);
461 CERROR("class_config_process_llog failed: rc = %d\n", rc);
463 err = obd_disconnect(exp, 0);
466 LCFG_INIT(lcfg, LCFG_CLEANUP, name);
467 err = class_process_config(&lcfg);
472 LCFG_INIT(lcfg, LCFG_DETACH, name);
473 err = class_process_config(&lcfg);
478 LCFG_INIT(lcfg, LCFG_DEL_UUID, name);
479 lcfg.lcfg_inllen1 = strlen(peer) + 1;
480 lcfg.lcfg_inlbuf1 = peer;
481 err = class_process_config(&lcfg);
490 /* parse host:/mdsname/profile string */
491 int ll_parse_mount_target(const char *target, char **mdsnid,
492 char **mdsname, char **profile)
494 static char buf[256];
498 strncpy(buf, target, 255);
500 if ((s = strchr(buf, ':'))) {
507 if ((s = strchr(*mdsname, '/'))) {
518 #define ENV_LUSTRE_MNTPNT "LIBLUSTRE_MOUNT_POINT"
519 #define ENV_LUSTRE_MNTTGT "LIBLUSTRE_MOUNT_TARGET"
520 #define ENV_LUSTRE_TIMEOUT "LIBLUSTRE_TIMEOUT"
521 #define ENV_LUSTRE_DUMPFILE "LIBLUSTRE_DUMPFILE"
523 extern int _sysio_native_init();
525 extern unsigned int obd_timeout;
527 /* global variables */
528 int g_zconf = 0; /* zeroconf or dumpfile */
529 char *g_zconf_mdsname = NULL; /* mdsname, for zeroconf */
530 char *g_zconf_mdsnid = NULL; /* mdsnid, for zeroconf */
531 char *g_zconf_profile = NULL; /* profile, for zeroconf */
534 void __liblustre_setup_(void)
536 char *lustre_path = NULL;
538 char *timeout = NULL;
539 char *dumpfile = NULL;
540 char *root_driver = "native";
541 char *lustre_driver = "llite";
542 char *root_path = "/";
543 unsigned mntflgs = 0;
546 lustre_path = getenv(ENV_LUSTRE_MNTPNT);
548 lustre_path = "/mnt/lustre";
551 target = getenv(ENV_LUSTRE_MNTTGT);
553 dumpfile = getenv(ENV_LUSTRE_DUMPFILE);
555 CERROR("Neither mount target, nor dumpfile\n");
559 printf("LibLustre: mount point %s, dumpfile %s\n",
560 lustre_path, dumpfile);
562 if (ll_parse_mount_target(target,
566 CERROR("mal-formed target %s \n", target);
570 printf("LibLustre: mount point %s, target %s\n",
571 lustre_path, target);
574 timeout = getenv(ENV_LUSTRE_TIMEOUT);
576 obd_timeout = (unsigned int) atoi(timeout);
577 printf("LibLustre: set obd timeout as %u seconds\n",
581 if (_sysio_init() != 0) {
582 perror("init sysio");
586 /* cygwin don't need native driver */
588 _sysio_native_init();
591 err = _sysio_mount_root(root_path, root_driver, mntflgs, NULL);
599 portal_subsystem_debug = 0;
603 err = lllib_init(dumpfile);
605 perror("init llite driver");
609 err = mount("/", lustre_path, lustre_driver, mntflgs, NULL);
612 perror(lustre_driver);
617 __sysio_hook_sys_enter = llu_check_request;
618 __sysio_hook_sys_leave = NULL;
622 void __liblustre_cleanup_(void)