Whamcloud - gitweb
* Landed b_cray_portals_merge.
[fs/lustre-release.git] / lustre / liblustre / llite_lib.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Lustre Light Super operations
5  *
6  *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
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.
13  *
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.
18  *
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.
22  */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <sys/types.h>
28 #include <sys/queue.h>
29
30 #include <netinet/in.h>
31 #include <sys/socket.h>
32 #include <arpa/inet.h>
33
34 #include <sysio.h>
35 #include <fs.h>
36 #include <mount.h>
37 #include <inode.h>
38 #include <file.h>
39
40 /* both sys/queue.h (libsysio require it) and portals/lists.h have definition
41  * of 'LIST_HEAD'. undef it to suppress warnings
42  */
43 #undef LIST_HEAD
44
45 #include <portals/api-support.h> /* needed for ptpctl.h */
46 #include <portals/ptlctl.h>     /* needed for parse_dump */
47 #include <procbridge.h>
48
49 #include "llite_lib.h"
50
51 unsigned int portal_subsystem_debug = ~0 - (S_PORTALS | S_QSWNAL | S_SOCKNAL |
52                                             S_GMNAL | S_IBNAL);
53
54 ptl_handle_ni_t         tcpnal_ni;
55 struct task_struct     *current;
56
57 /* portals interfaces */
58
59 struct ldlm_namespace;
60 struct ldlm_res_id;
61 struct obd_import;
62
63 void *inter_module_get(char *arg)
64 {
65         if (!strcmp(arg, "tcpnal_ni"))
66                 return &tcpnal_ni;
67         else if (!strcmp(arg, "ldlm_cli_cancel_unused"))
68                 return ldlm_cli_cancel_unused;
69         else if (!strcmp(arg, "ldlm_namespace_cleanup"))
70                 return ldlm_namespace_cleanup;
71         else if (!strcmp(arg, "ldlm_replay_locks"))
72                 return ldlm_replay_locks;
73         else
74                 return NULL;
75 }
76
77 /* XXX move to proper place */
78 char *portals_nid2str(int nal, ptl_nid_t nid, char *str)
79 {
80         switch(nal){
81         case TCPNAL:
82                 /* userspace NAL */
83         case SOCKNAL:
84                 sprintf(str, "%u:%d.%d.%d.%d", (__u32)(nid >> 32),
85                         HIPQUAD(nid));
86                 break;
87         case QSWNAL:
88         case GMNAL:
89         case IBNAL:
90         case SCIMACNAL:
91                 sprintf(str, "%u:%u", (__u32)(nid >> 32), (__u32)nid);
92                 break;
93         default:
94                 return NULL;
95         }
96         return str;
97 }
98
99 void init_current(char *comm)
100
101         current = malloc(sizeof(*current));
102         current->fs = malloc(sizeof(*current->fs));
103         current->fs->umask = umask(0777);
104         umask(current->fs->umask);
105         strncpy(current->comm, comm, sizeof(current->comm));
106         current->pid = getpid();
107         current->fsuid = 0;
108         current->fsgid = 0;
109         current->cap_effective = -1;
110         memset(&current->pending, 0, sizeof(current->pending));
111 }
112
113 /* FIXME */
114 void generate_random_uuid(unsigned char uuid_out[16])
115 {
116         int *arr = (int*)uuid_out;
117         int i;
118
119         for (i = 0; i < sizeof(uuid_out)/sizeof(int); i++)
120                 arr[i] = rand();
121 }
122
123 ptl_nid_t tcpnal_mynid;
124
125 int init_lib_portals()
126 {
127         int max_interfaces;
128         int rc;
129         ENTRY;
130
131         rc = PtlInit(&max_interfaces);
132         if (rc != PTL_OK) {
133                 CERROR("PtlInit failed: %d\n", rc);
134                 RETURN (-ENXIO);
135         }
136         RETURN(0);
137 }
138
139 int
140 libcfs_nal_cmd(struct portals_cfg *pcfg)
141 {
142         /* handle portals command if we want */
143         return 0;
144 }
145
146 extern int class_handle_ioctl(unsigned int cmd, unsigned long arg);
147
148 int lib_ioctl_nalcmd(int dev_id, int opc, void * ptr)
149 {
150         struct portal_ioctl_data *ptldata;
151
152         if (opc == IOC_PORTAL_NAL_CMD) {
153                 ptldata = (struct portal_ioctl_data *) ptr;
154
155                 if (ptldata->ioc_nal_cmd == NAL_CMD_REGISTER_MYNID) {
156                         tcpnal_mynid = ptldata->ioc_nid;
157                         printf("mynid: %u.%u.%u.%u\n",
158                                 (unsigned)(tcpnal_mynid>>24) & 0xFF,
159                                 (unsigned)(tcpnal_mynid>>16) & 0xFF,
160                                 (unsigned)(tcpnal_mynid>>8) & 0xFF,
161                                 (unsigned)(tcpnal_mynid) & 0xFF);
162                 }
163         }
164
165         return (0);
166 }
167
168 int lib_ioctl(int dev_id, int opc, void * ptr)
169 {
170         int rc;
171
172         if (dev_id == OBD_DEV_ID) {
173                 struct obd_ioctl_data *ioc = ptr;
174
175                 //XXX hack!!!
176                 ioc->ioc_plen1 = ioc->ioc_inllen1;
177                 ioc->ioc_pbuf1 = ioc->ioc_bulk;
178                 //XXX
179
180                 rc = class_handle_ioctl(opc, (unsigned long)ptr);
181
182                 printf ("proccssing ioctl cmd: %x, rc %d\n", opc,  rc);
183
184                 if (rc)
185                         return rc;
186         }
187         return (0);
188 }
189
190 int lllib_init(char *dumpfile)
191 {
192         if (!g_zconf) {
193                 /* this parse only get my nid from config file
194                  * before initialize portals
195                  */
196                 if (parse_dump(dumpfile, lib_ioctl_nalcmd))
197                         return -1;
198         } else {
199                 /* XXX need setup mynid before tcpnal initialize */
200                 tcpnal_mynid = ((uint64_t)getpid() << 32) | time(0);
201                 printf("LibLustre: TCPNAL NID: %016llx\n", tcpnal_mynid);
202         }
203
204         init_current("dummy");
205         if (init_obdclass() ||
206             init_lib_portals() ||
207             ptlrpc_init() ||
208             mdc_init() ||
209             lov_init() ||
210             osc_init())
211                 return -1;
212
213         if (!g_zconf && parse_dump(dumpfile, lib_ioctl))
214                 return -1;
215
216         return _sysio_fssw_register("llite", &llu_fssw_ops);
217 }
218  
219 #if 0
220 static void llu_check_request()
221 {
222         liblustre_wait_event(0);
223 }
224 #endif
225
226 int liblustre_process_log(struct config_llog_instance *cfg, int allow_recov)
227 {
228         struct lustre_cfg lcfg;
229         char  *peer = "MDS_PEER_UUID";
230         struct obd_device *obd;
231         struct lustre_handle mdc_conn = {0, };
232         struct obd_export *exp;
233         char  *name = "mdc_dev";
234         class_uuid_t uuid;
235         struct obd_uuid mdc_uuid;
236         struct llog_ctxt *ctxt;
237         ptl_nid_t nid = 0;
238         int nal, err, rc = 0;
239         ENTRY;
240
241         generate_random_uuid(uuid);
242         class_uuid_unparse(uuid, &mdc_uuid);
243
244         if (ptl_parse_nid(&nid, g_zconf_mdsnid)) {
245                 CERROR("Can't parse NID %s\n", g_zconf_mdsnid);
246                 RETURN(-EINVAL);
247         }
248
249         nal = ptl_name2nal("tcp");
250         if (nal <= 0) {
251                 CERROR("Can't parse NAL tcp\n");
252                 RETURN(-EINVAL);
253         }
254         LCFG_INIT(lcfg, LCFG_ADD_UUID, NULL);
255         lcfg.lcfg_nid = nid;
256         lcfg.lcfg_inllen1 = strlen(peer) + 1;
257         lcfg.lcfg_inlbuf1 = peer;
258         lcfg.lcfg_nal = nal;
259         err = class_process_config(&lcfg);
260         if (err < 0)
261                 GOTO(out, err);
262
263         LCFG_INIT(lcfg, LCFG_ATTACH, name);
264         lcfg.lcfg_inlbuf1 = "mdc";
265         lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
266         lcfg.lcfg_inlbuf2 = mdc_uuid.uuid;
267         lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
268         err = class_process_config(&lcfg);
269         if (err < 0)
270                 GOTO(out_del_uuid, err);
271
272         LCFG_INIT(lcfg, LCFG_SETUP, name);
273         lcfg.lcfg_inlbuf1 = g_zconf_mdsname;
274         lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
275         lcfg.lcfg_inlbuf2 = peer;
276         lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
277         err = class_process_config(&lcfg);
278         if (err < 0)
279                 GOTO(out_detach, err);
280         
281         obd = class_name2obd(name);
282         if (obd == NULL)
283                 GOTO(out_cleanup, err = -EINVAL);
284
285         /* Disable initial recovery on this import */
286         err = obd_set_info(obd->obd_self_export,
287                            strlen("initial_recov"), "initial_recov",
288                            sizeof(allow_recov), &allow_recov);
289
290         err = obd_connect(&mdc_conn, obd, &mdc_uuid);
291         if (err) {
292                 CERROR("cannot connect to %s: rc = %d\n",
293                         g_zconf_mdsname, err);
294                 GOTO(out_cleanup, err);
295         }
296         
297         exp = class_conn2export(&mdc_conn);
298         
299         ctxt = exp->exp_obd->obd_llog_ctxt[LLOG_CONFIG_REPL_CTXT];
300         rc = class_config_parse_llog(ctxt, g_zconf_profile, cfg);
301         if (rc) {
302                 CERROR("class_config_parse_llog failed: rc = %d\n", rc);
303         }
304
305         err = obd_disconnect(exp, 0);
306
307 out_cleanup:
308         LCFG_INIT(lcfg, LCFG_CLEANUP, name);
309         err = class_process_config(&lcfg);
310         if (err < 0)
311                 GOTO(out, err);
312
313 out_detach:
314         LCFG_INIT(lcfg, LCFG_DETACH, name);
315         err = class_process_config(&lcfg);
316         if (err < 0)
317                 GOTO(out, err);
318
319 out_del_uuid:
320         LCFG_INIT(lcfg, LCFG_DEL_UUID, name);
321         lcfg.lcfg_inllen1 = strlen(peer) + 1;
322         lcfg.lcfg_inlbuf1 = peer;
323         err = class_process_config(&lcfg);
324
325 out:
326         if (rc == 0)
327                 rc = err;
328         
329         RETURN(rc);
330 }
331
332 static void sighandler_USR1(int signum)
333 {
334         /* do nothing */
335 }
336
337 /* parse host:/mdsname/profile string */
338 int ll_parse_mount_target(const char *target, char **mdsnid,
339                           char **mdsname, char **profile)
340 {
341         static char buf[256];
342         char *s;
343
344         buf[255] = 0;
345         strncpy(buf, target, 255);
346
347         if ((s = strchr(buf, ':'))) {
348                 *mdsnid = buf;
349                 *s = '\0';
350                                                                                                                         
351                 while (*++s == '/')
352                         ;
353                 *mdsname = s;
354                 if ((s = strchr(*mdsname, '/'))) {
355                         *s = '\0';
356                         *profile = s + 1;
357                         return 0;
358                 }
359         }
360
361         return -1;
362 }
363
364 /* env variables */
365 #define ENV_LUSTRE_MNTPNT               "LIBLUSTRE_MOUNT_POINT"
366 #define ENV_LUSTRE_MNTTGT               "LIBLUSTRE_MOUNT_TARGET"
367 #define ENV_LUSTRE_TIMEOUT              "LIBLUSTRE_TIMEOUT"
368 #define ENV_LUSTRE_DUMPFILE             "LIBLUSTRE_DUMPFILE"
369
370 extern int _sysio_native_init();
371
372 extern unsigned int obd_timeout;
373
374 /* global variables */
375 int     g_zconf = 0;            /* zeroconf or dumpfile */
376 char   *g_zconf_mdsname = NULL; /* mdsname, for zeroconf */
377 char   *g_zconf_mdsnid = NULL;  /* mdsnid, for zeroconf */
378 char   *g_zconf_profile = NULL; /* profile, for zeroconf */
379
380
381 void __liblustre_setup_(void)
382 {
383         char *lustre_path = NULL;
384         char *target = NULL;
385         char *timeout = NULL;
386         char *dumpfile = NULL;
387         char *root_driver = "native";
388         char *lustre_driver = "llite";
389         char *root_path = "/";
390         unsigned mntflgs = 0;
391
392         int err;
393
394         /* consider tha case of starting multiple liblustre instances
395          * at a same time on single node.
396          */
397         srand(time(NULL) + getpid());
398
399         signal(SIGUSR1, sighandler_USR1);
400
401         lustre_path = getenv(ENV_LUSTRE_MNTPNT);
402         if (!lustre_path) {
403                 lustre_path = "/mnt/lustre";
404         }
405
406         target = getenv(ENV_LUSTRE_MNTTGT);
407         if (!target) {
408                 dumpfile = getenv(ENV_LUSTRE_DUMPFILE);
409                 if (!dumpfile) {
410                         CERROR("Neither mount target, nor dumpfile\n");
411                         exit(1);
412                 }
413                 g_zconf = 0;
414                 printf("LibLustre: mount point %s, dumpfile %s\n",
415                         lustre_path, dumpfile);
416         } else {
417                 if (ll_parse_mount_target(target,
418                                           &g_zconf_mdsnid,
419                                           &g_zconf_mdsname,
420                                           &g_zconf_profile)) {
421                         CERROR("mal-formed target %s \n", target);
422                         exit(1);
423                 }
424                 g_zconf = 1;
425                 printf("LibLustre: mount point %s, target %s\n",
426                         lustre_path, target);
427         }
428
429         timeout = getenv(ENV_LUSTRE_TIMEOUT);
430         if (timeout) {
431                 obd_timeout = (unsigned int) atoi(timeout);
432                 printf("LibLustre: set obd timeout as %u seconds\n",
433                         obd_timeout);
434         }
435
436         if (_sysio_init() != 0) {
437                 perror("init sysio");
438                 exit(1);
439         }
440
441         /* cygwin don't need native driver */
442 #ifndef __CYGWIN__
443         _sysio_native_init();
444 #endif
445
446         err = _sysio_mount_root(root_path, root_driver, mntflgs, NULL);
447         if (err) {
448                 perror(root_driver);
449                 exit(1);
450         }
451
452 #if 1
453         portal_debug = 0;
454         portal_subsystem_debug = 0;
455 #endif
456         err = lllib_init(dumpfile);
457         if (err) {
458                 perror("init llite driver");
459                 exit(1);
460         }       
461
462         err = mount("/", lustre_path, lustre_driver, mntflgs, NULL);
463         if (err) {
464                 errno = -err;
465                 perror(lustre_driver);
466                 exit(1);
467         }
468
469 #if 0
470         __sysio_hook_sys_enter = llu_check_request;
471         __sysio_hook_sys_leave = NULL;
472 #endif
473 }
474
475 void __liblustre_cleanup_(void)
476 {
477         _sysio_shutdown();
478         PtlFini();
479 }