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