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