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