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
index b11de88..ec0d06c 100644 (file)
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define DEBUG_SUBSYSTEM S_LLITE
-
 #include <stdlib.h>
 #include <string.h>
-#include <error.h>
 #include <assert.h>
 #include <sys/types.h>
 #include <sys/queue.h>
 
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
 #include <sysio.h>
 #include <fs.h>
 #include <mount.h>
 #include <inode.h>
 #include <file.h>
 
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-
 #include <portals/api-support.h> /* needed for ptpctl.h */
 #include <portals/ptlctl.h>    /* needed for parse_dump */
+#include <procbridge.h>
 
 #include "llite_lib.h"
 
@@ -54,7 +52,13 @@ struct obd_class_user_state ocus;
 ptl_handle_ni_t *
 kportal_get_ni (int nal)
 {
-        return &tcpnal_ni;
+        switch (nal)
+        {
+        case SOCKNAL:
+                return &tcpnal_ni;
+        default:
+                return NULL;
+        }
 }
 
 inline void
@@ -67,10 +71,6 @@ struct ldlm_namespace;
 struct ldlm_res_id;
 struct obd_import;
 
-extern int ldlm_cli_cancel_unused(struct ldlm_namespace *ns, struct ldlm_res_id *res_id, int flags);
-extern int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int local_only);
-extern int ldlm_replay_locks(struct obd_import *imp);
-
 void *inter_module_get(char *arg)
 {
         if (!strcmp(arg, "tcpnal_ni"))
@@ -85,6 +85,29 @@ void *inter_module_get(char *arg)
                 return NULL;
 }
 
+/* XXX move to proper place */
+char *portals_nid2str(int nal, ptl_nid_t nid, char *str)
+{
+        switch(nal){
+        case TCPNAL:
+                /* userspace NAL */
+        case SOCKNAL:
+                sprintf(str, "%u:%d.%d.%d.%d", (__u32)(nid >> 32),
+                        HIPQUAD(nid));
+                break;
+        case QSWNAL:
+        case GMNAL:
+        case IBNAL:
+        case TOENAL:
+        case SCIMACNAL:
+                sprintf(str, "%u:%u", (__u32)(nid >> 32), (__u32)nid);
+                break;
+        default:
+                return NULL;
+        }
+        return str;
+}
+
 void init_current(char *comm)
 { 
         current = malloc(sizeof(*current));
@@ -95,15 +118,26 @@ void init_current(char *comm)
         current->pid = getpid();
         current->fsuid = 0;
         current->fsgid = 0;
-        current->cap_effective = 0;
+        current->cap_effective = -1;
         memset(&current->pending, 0, sizeof(current->pending));
 }
 
+/* FIXME */
+void generate_random_uuid(unsigned char uuid_out[16])
+{
+        int *arr = (int*)uuid_out;
+        int i;
+
+        for (i = 0; i < sizeof(uuid_out)/sizeof(int); i++)
+                arr[i] = rand();
+}
+
 ptl_nid_t tcpnal_mynid;
 
 int init_lib_portals()
 {
         int rc;
+        ENTRY;
 
         PtlInit();
         rc = PtlNIInit(procbridge_interface, 0, 0, 0, &tcpnal_ni);
@@ -113,58 +147,36 @@ int init_lib_portals()
                 RETURN (rc);
         }
         PtlNIDebug(tcpnal_ni, ~0);
-        return rc;
+        RETURN(rc);
 }
 
-extern int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd, unsigned long arg);
+int
+kportal_nal_cmd(struct portals_cfg *pcfg)
+{
+        /* handle portals command if we want */
+        return 0;
+}
 
-struct mount_option_s mount_option = {NULL, NULL};
+extern int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd, unsigned long arg);
 
-/* FIXME simple arg parser FIXME */
-void parse_mount_options(void *arg)
+int lib_ioctl_nalcmd(int dev_id, int opc, void * ptr)
 {
-        char *buf = NULL;
-        struct obd_ioctl_data *data;
-        char *ptr, *comma, *eq, **tgt, *v;
-        int len;
-
-        if (obd_ioctl_getdata(&buf, &len, arg)) {
-                CERROR("OBD ioctl: data error\n");
-                return;
-        }
-        data = (struct obd_ioctl_data *)buf;
-        ptr = data->ioc_inlbuf1;
-        printf("mount option: %s\n", ptr);
-
-        while (ptr) {
-                eq = strchr(ptr, '=');
-                if (!eq)
-                        return;
-
-                *eq = 0;
-                if (!strcmp("osc", ptr))
-                        tgt = &mount_option.osc_uuid;
-                else if (!strcmp("mdc", ptr))
-                        tgt = &mount_option.mdc_uuid;
-                else {
-                        printf("Unknown mount option %s\n", ptr);
-                        return;
+        struct portal_ioctl_data *ptldata;
+
+        if (opc == IOC_PORTAL_NAL_CMD) {
+                ptldata = (struct portal_ioctl_data *) ptr;
+
+                if (ptldata->ioc_nal_cmd == NAL_CMD_REGISTER_MYNID) {
+                        tcpnal_mynid = ptldata->ioc_nid;
+                        printf("mynid: %u.%u.%u.%u\n",
+                                (unsigned)(tcpnal_mynid>>24) & 0xFF,
+                                (unsigned)(tcpnal_mynid>>16) & 0xFF,
+                                (unsigned)(tcpnal_mynid>>8) & 0xFF,
+                                (unsigned)(tcpnal_mynid) & 0xFF);
                 }
-
-                v = eq + 1;
-                comma = strchr(v, ',');
-                if (comma) {
-                        *comma = 0;
-                        ptr = comma + 1;
-                } else
-                        ptr = NULL;
-
-                *tgt = malloc(strlen(v)+1);
-                strcpy(*tgt, v);
         }
 
-        if (buf)
-                obd_ioctl_freedata(buf, len);
+       return (0);
 }
 
 int lib_ioctl(int dev_id, int opc, void * ptr)
@@ -174,18 +186,14 @@ int lib_ioctl(int dev_id, int opc, void * ptr)
        if (dev_id == OBD_DEV_ID) {
                 struct obd_ioctl_data *ioc = ptr;
 
-                if (opc == OBD_IOC_MOUNTOPT) {
-                        parse_mount_options(ptr);
-                        return 0;
-                }
+                //XXX hack!!!
+                ioc->ioc_plen1 = ioc->ioc_inllen1;
+                ioc->ioc_pbuf1 = ioc->ioc_bulk;
+                //XXX
 
-               rc = class_handle_ioctl(&ocus, opc, (unsigned long)ptr);
+                rc = class_handle_ioctl(&ocus, opc, (unsigned long)ptr);
 
-               /* you _may_ need to call obd_ioctl_unpack or some
-                  other verification function if you want to use ioc
-                  directly here */
-               printf ("processing ioctl cmd: %x buf len: %d, rc %d\n", 
-                       opc,  ioc->ioc_len, rc);
+                printf ("proccssing ioctl cmd: %x, rc %d\n", opc,  rc);
 
                 if (rc)
                         return rc;
@@ -193,11 +201,22 @@ int lib_ioctl(int dev_id, int opc, void * ptr)
        return (0);
 }
 
-int lllib_init(char *arg)
+int lllib_init(char *dumpfile)
 {
-       tcpnal_mynid = ntohl(inet_addr(arg));
         INIT_LIST_HEAD(&ocus.ocus_conns);
 
+        if (!g_zconf) {
+                /* this parse only get my nid from config file
+                 * before initialize portals
+                 */
+                if (parse_dump(dumpfile, lib_ioctl_nalcmd))
+                        return -1;
+        } else {
+                /* XXX need setup mynid before tcpnal initialize */
+                tcpnal_mynid = ((uint64_t)getpid() << 32) | time(0);
+                printf("set tcpnal mynid: %016llx\n", tcpnal_mynid);
+        }
+
         init_current("dummy");
         if (init_obdclass() ||
             init_lib_portals() ||
@@ -208,19 +227,250 @@ int lllib_init(char *arg)
             osc_init())
                 return -1;
 
-       if (parse_dump("/tmp/DUMP_FILE", lib_ioctl))
+        if (!g_zconf && parse_dump(dumpfile, lib_ioctl))
                 return -1;
 
         return _sysio_fssw_register("llite", &llu_fssw_ops);
 }
+#if 0
+static void llu_check_request()
+{
+        liblustre_wait_event(0);
+}
+#endif
 
-/* FIXME */
-void generate_random_uuid(unsigned char uuid_out[16])
+int liblustre_process_log(struct config_llog_instance *cfg)
 {
-        int *arr = (int*)uuid_out;
-        int i;
+        struct lustre_cfg lcfg;
+        char  *peer = "MDS_PEER_UUID";
+        struct obd_device *obd;
+        struct lustre_handle mdc_conn = {0, };
+        struct obd_export *exp;
+        char  *name = "mdc_dev";
+        class_uuid_t uuid;
+        struct obd_uuid mdc_uuid;
+        struct llog_ctxt *ctxt;
+        ptl_nid_t nid = 0;
+        int nal, err, rc = 0;
+        ENTRY;
+
+        generate_random_uuid(uuid);
+        class_uuid_unparse(uuid, &mdc_uuid);
+
+        if (ptl_parse_nid(&nid, g_zconf_mdsnid)) {
+                CERROR("Can't parse NID %s\n", g_zconf_mdsnid);
+                RETURN(-EINVAL);
+        }
+        nal = ptl_name2nal("tcp");
+        if (nal <= 0) {
+                CERROR("Can't parse NAL tcp\n");
+                RETURN(-EINVAL);
+        }
+        LCFG_INIT(lcfg, LCFG_ADD_UUID, NULL);
+        lcfg.lcfg_nid = nid;
+        lcfg.lcfg_inllen1 = strlen(peer) + 1;
+        lcfg.lcfg_inlbuf1 = peer;
+        lcfg.lcfg_nal = nal;
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out, err);
+
+        LCFG_INIT(lcfg, LCFG_ATTACH, name);
+        lcfg.lcfg_inlbuf1 = "mdc";
+        lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
+        lcfg.lcfg_inlbuf2 = mdc_uuid.uuid;
+        lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out_del_uuid, err);
+
+        LCFG_INIT(lcfg, LCFG_SETUP, name);
+        lcfg.lcfg_inlbuf1 = g_zconf_mdsname;
+        lcfg.lcfg_inllen1 = strlen(lcfg.lcfg_inlbuf1) + 1;
+        lcfg.lcfg_inlbuf2 = peer;
+        lcfg.lcfg_inllen2 = strlen(lcfg.lcfg_inlbuf2) + 1;
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out_detach, err);
+        
+        obd = class_name2obd(name);
+        if (obd == NULL)
+                GOTO(out_cleanup, err = -EINVAL);
+
+        err = obd_connect(&mdc_conn, obd, &mdc_uuid);
+        if (err) {
+                CERROR("cannot connect to %s: rc = %d\n",
+                        g_zconf_mdsname, err);
+                GOTO(out_cleanup, err);
+        }
+        
+        exp = class_conn2export(&mdc_conn);
+        
+        ctxt = exp->exp_obd->obd_llog_ctxt[LLOG_CONFIG_REPL_CTXT];
+        rc = class_config_parse_llog(ctxt, g_zconf_profile, cfg);
+        if (rc) {
+                CERROR("class_config_parse_llog failed: rc = %d\n", rc);
+        }
 
-        for (i = 0; i < sizeof(uuid_out)/sizeof(int); i++)
-                arr[i] = rand();
+        err = obd_disconnect(exp, 0);
+
+out_cleanup:
+        LCFG_INIT(lcfg, LCFG_CLEANUP, name);
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out, err);
+
+out_detach:
+        LCFG_INIT(lcfg, LCFG_DETACH, name);
+        err = class_process_config(&lcfg);
+        if (err < 0)
+                GOTO(out, err);
+
+out_del_uuid:
+        LCFG_INIT(lcfg, LCFG_DEL_UUID, name);
+        lcfg.lcfg_inllen1 = strlen(peer) + 1;
+        lcfg.lcfg_inlbuf1 = peer;
+        err = class_process_config(&lcfg);
+
+out:
+        if (rc == 0)
+                rc = err;
+        
+        RETURN(rc);
+}
+
+static void sighandler_USR1(int signum)
+{
+        /* do nothing */
+}
+
+/* parse host:/mdsname/profile string */
+int ll_parse_mount_target(const char *target, char **mdsnid,
+                          char **mdsname, char **profile)
+{
+        static char buf[256];
+        char *s;
+
+        buf[255] = 0;
+        strncpy(buf, target, 255);
+
+        if ((s = strchr(buf, ':'))) {
+                *mdsnid = buf;
+                *s = '\0';
+                                                                                                                        
+                while (*++s == '/')
+                        ;
+                *mdsname = s;
+                if ((s = strchr(*mdsname, '/'))) {
+                        *s = '\0';
+                        *profile = s + 1;
+                        return 0;
+                }
+        }
+
+        return -1;
+}
+
+/* env variables */
+#define ENV_LUSTRE_MNTPNT               "LIBLUSTRE_MOUNT_POINT"
+#define ENV_LUSTRE_MNTTGT               "LIBLUSTRE_MOUNT_TARGET"
+#define ENV_LUSTRE_DUMPFILE             "LIBLUSTRE_DUMPFILE"
+
+extern int _sysio_native_init();
+
+/* global variables */
+int     g_zconf = 0;            /* zeroconf or dumpfile */
+char   *g_zconf_mdsname = NULL; /* mdsname, for zeroconf */
+char   *g_zconf_mdsnid = NULL;  /* mdsnid, for zeroconf */
+char   *g_zconf_profile = NULL; /* profile, for zeroconf */
+
+
+void __liblustre_setup_(void)
+{
+        char *lustre_path = NULL;
+        char *target = NULL;
+        char *dumpfile = NULL;
+        char *root_driver = "native";
+        char *lustre_driver = "llite";
+        char *root_path = "/";
+        unsigned mntflgs = 0;
+
+       int err;
+
+        srand(time(NULL));
+
+        signal(SIGUSR1, sighandler_USR1);
+
+       lustre_path = getenv(ENV_LUSTRE_MNTPNT);
+       if (!lustre_path) {
+                lustre_path = "/mnt/lustre";
+       }
+
+        target = getenv(ENV_LUSTRE_MNTTGT);
+        if (!target) {
+                dumpfile = getenv(ENV_LUSTRE_DUMPFILE);
+                if (!dumpfile) {
+                        CERROR("Neither mount target, nor dumpfile\n");
+                        exit(1);
+                }
+                g_zconf = 0;
+                printf("LibLustre: mount point %s, dumpfile %s\n",
+                        lustre_path, dumpfile);
+        } else {
+                if (ll_parse_mount_target(target,
+                                          &g_zconf_mdsnid,
+                                          &g_zconf_mdsname,
+                                          &g_zconf_profile)) {
+                        CERROR("mal-formed target %s \n", target);
+                        exit(1);
+                }
+                g_zconf = 1;
+                printf("LibLustre: mount point %s, target %s\n",
+                        lustre_path, target);
+        }
+
+       if (_sysio_init() != 0) {
+               perror("init sysio");
+               exit(1);
+       }
+
+        /* cygwin don't need native driver */
+#ifndef __CYGWIN__
+        _sysio_native_init();
+#endif
+
+       err = _sysio_mount_root(root_path, root_driver, mntflgs, NULL);
+       if (err) {
+               perror(root_driver);
+               exit(1);
+       }
+
+#if 1
+       portal_debug = 0;
+       portal_subsystem_debug = 0;
+#endif
+       err = lllib_init(dumpfile);
+       if (err) {
+               perror("init llite driver");
+               exit(1);
+       }       
+
+        err = mount("/", lustre_path, lustre_driver, mntflgs, NULL);
+       if (err) {
+               errno = -err;
+               perror(lustre_driver);
+               exit(1);
+       }
+
+#if 0
+        __sysio_hook_sys_enter = llu_check_request;
+        __sysio_hook_sys_leave = NULL;
+#endif
 }
 
+void __liblustre_cleanup_(void)
+{
+       _sysio_shutdown();
+        PtlFini();
+}