Whamcloud - gitweb
b=15516
[fs/lustre-release.git] / lustre / obdclass / obd_config.c
index e4b3ed3..25f9d5a 100644 (file)
 #include <lprocfs_status.h>
 #include <libcfs/list.h>
 #include <lustre_param.h>
+#include <class_hash.h>
+
+extern struct lustre_hash_operations uuid_hash_operations;
+extern struct lustre_hash_operations nid_hash_operations;
 
 /*********** string parsing utils *********/
 
@@ -98,7 +102,7 @@ int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
         *endp = '\0';
         *nid = libcfs_str2nid(buf);
         if (*nid == LNET_NID_ANY) {
-                LCONSOLE_ERROR("Can't parse NID '%s'\n", buf);
+                LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", buf);
                 *endp = tmp;
                 return -EINVAL;
         }
@@ -116,8 +120,9 @@ EXPORT_SYMBOL(class_parse_nid);
 
 /********************** class fns **********************/
 
-/* Create a new device and set the type, name and uuid.  If
- * successful, the new device can be accessed by either name or uuid.
+/**
+ * Create a new device and set the type, name and uuid.  If successful, the new
+ * device can be accessed by either name or uuid.
  */
 int class_attach(struct lustre_cfg *lcfg)
 {
@@ -147,26 +152,6 @@ int class_attach(struct lustre_cfg *lcfg)
         CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
                MKSTR(typename), MKSTR(name), MKSTR(uuid));
 
-        /* Mountconf transitional hack, should go away after 1.6.
-           1.4.7 uses the old names, so translate back if the
-           mountconf flag is set.
-           1.6 should set this flag, and translate the other way here
-           if not set. */
-        if (lcfg->lcfg_flags & LCFG_FLG_MOUNTCONF){
-                char *tmp = NULL;
-                if (strcmp(typename, "mds") == 0)
-                        tmp = "mdt";
-                if (strcmp(typename, "mdt") == 0)
-                        tmp = "mds";
-                if (strcmp(typename, "osd") == 0)
-                        tmp = "obdfilter";
-                if (tmp) {
-                        LCONSOLE_WARN("Using type %s for %s %s\n", tmp,
-                                      MKSTR(typename), MKSTR(name));
-                        typename = tmp;
-                }
-        }
-
         obd = class_newdev(typename, name);
         if (IS_ERR(obd)) {
                 /* Already exists or out of obds */
@@ -184,11 +169,16 @@ int class_attach(struct lustre_cfg *lcfg)
         LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0, "%p obd_name %s != %s\n",
                  obd, obd->obd_name, name);
 
+        rwlock_init(&obd->obd_pool_lock);
+        obd->obd_pool_limit = 0;
+        obd->obd_pool_slv = 0;
+
         CFS_INIT_LIST_HEAD(&obd->obd_exports);
         CFS_INIT_LIST_HEAD(&obd->obd_exports_timed);
+        CFS_INIT_LIST_HEAD(&obd->obd_nid_stats);
+        spin_lock_init(&obd->obd_nid_lock);
         spin_lock_init(&obd->obd_dev_lock);
         sema_init(&obd->obd_dev_sem, 1);
-        sema_init(&obd->obd_proc_exp_sem, 1);
         spin_lock_init(&obd->obd_osfs_lock);
         /* obd->obd_osfs_age must be set to a value in the distant
          * past to guarantee a fresh statfs is fetched on mount. */
@@ -199,16 +189,20 @@ int class_attach(struct lustre_cfg *lcfg)
         cfs_init_timer(&obd->obd_recovery_timer);
         spin_lock_init(&obd->obd_processing_task_lock);
         cfs_waitq_init(&obd->obd_next_transno_waitq);
-        CFS_INIT_LIST_HEAD(&obd->obd_recovery_queue);
-        CFS_INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
+        cfs_waitq_init(&obd->obd_evict_inprogress_waitq);
+        CFS_INIT_LIST_HEAD(&obd->obd_req_replay_queue);
+        CFS_INIT_LIST_HEAD(&obd->obd_lock_replay_queue);
+        CFS_INIT_LIST_HEAD(&obd->obd_final_req_queue);
+
+        llog_group_init(&obd->obd_olg, OBD_LLOG_GROUP);
 
         spin_lock_init(&obd->obd_uncommitted_replies_lock);
         CFS_INIT_LIST_HEAD(&obd->obd_uncommitted_replies);
 
         len = strlen(uuid);
         if (len >= sizeof(obd->obd_uuid)) {
-                CERROR("uuid must be < "LPSZ" bytes long\n",
-                       sizeof(obd->obd_uuid));
+                CERROR("uuid must be < %d bytes long\n",
+                       (int)sizeof(obd->obd_uuid));
                 GOTO(out, rc = -EINVAL);
         }
         memcpy(obd->obd_uuid.uuid, uuid, len);
@@ -273,18 +267,38 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
         obd->obd_starting = 1;
         spin_unlock(&obd->obd_dev_lock);
 
+        /* create an uuid-export hash body */
+        err = lustre_hash_init(&obd->obd_uuid_hash_body, "UUID_HASH", 
+                               128, &uuid_hash_operations);
+        if (err)
+                GOTO(err_hash, err);
+
+        /* create a nid-export hash body */
+        err = lustre_hash_init(&obd->obd_nid_hash_body, "NID_HASH", 
+                               128, &nid_hash_operations);
+        if (err)
+                GOTO(err_hash, err);
+
+        /* create a nid-stats hash body */
+        err = lustre_hash_init(&obd->obd_nid_stats_hash_body, "NID_STATS",
+                               128, &nid_stat_hash_operations);
+        if (err)
+                GOTO(err_hash, err);
+
         exp = class_new_export(obd, &obd->obd_uuid);
         if (IS_ERR(exp))
                 RETURN(PTR_ERR(exp));
+
         obd->obd_self_export = exp;
         list_del_init(&exp->exp_obd_chain_timed);
         class_export_put(exp);
 
-        err = obd_setup(obd, sizeof(*lcfg), lcfg);
+        err = obd_setup(obd, lcfg);
         if (err)
                 GOTO(err_exp, err);
 
         obd->obd_set_up = 1;
+        
         spin_lock(&obd->obd_dev_lock);
         /* cleanup drops this */
         class_incref(obd);
@@ -296,10 +310,14 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
         RETURN(0);
 
 err_exp:
-        CERROR("setup %s failed (%d)\n", obd->obd_name, err);
         class_unlink_export(obd->obd_self_export);
         obd->obd_self_export = NULL;
+err_hash:
+        lustre_hash_exit(&obd->obd_uuid_hash_body);
+        lustre_hash_exit(&obd->obd_nid_hash_body);
+        lustre_hash_exit(&obd->obd_nid_stats_hash_body);
         obd->obd_starting = 0;
+        CERROR("setup %s failed (%d)\n", obd->obd_name, err);
         RETURN(err);
 }
 
@@ -325,10 +343,10 @@ int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
                obd->obd_name, obd->obd_uuid.uuid);
 
         class_decref(obd);
-        
+
         /* not strictly necessary, but cleans up eagerly */
         obd_zombie_impexp_cull();
-        
+
         RETURN(0);
 }
 
@@ -387,7 +405,7 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
                                 obd->obd_force = 1;
                                 break;
                         case 'A':
-                                LCONSOLE_WARN("Failing over %s\n", 
+                                LCONSOLE_WARN("Failing over %s\n",
                                               obd->obd_name);
                                 obd->obd_fail = 1;
                                 obd->obd_no_transno = 1;
@@ -416,7 +434,6 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
                         dump_exports(obd);
                         /* Allow a failed cleanup to try again. */
                         obd->obd_stopping = 0;
-                        RETURN(-EBUSY);
                 }
 #endif
                 /* refcounf - 3 might be the number of real exports 
@@ -427,11 +444,18 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
                 dump_exports(obd);
                 class_disconnect_exports(obd);
         }
-
         LASSERT(obd->obd_self_export);
 
-        /* Precleanup stage 1, we must make sure all exports (other than the
-           self-export) get destroyed. */
+        /* destroy an uuid-export hash body */
+        lustre_hash_exit(&obd->obd_uuid_hash_body);
+
+        /* destroy a nid-export hash body */
+        lustre_hash_exit(&obd->obd_nid_hash_body);
+
+        /* destroy a nid-stats hash body */
+        lustre_hash_exit(&obd->obd_nid_stats_hash_body);
+
+        /* Precleanup, we must make sure all exports get destroyed. */
         err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
         if (err)
                 CERROR("Precleanup %s returned %d\n",
@@ -439,7 +463,6 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
 
         class_decref(obd);
         obd->obd_set_up = 0;
-
         RETURN(0);
 }
 
@@ -465,19 +488,15 @@ void class_decref(struct obd_device *obd)
         CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
 
         if ((refs == 1) && obd->obd_stopping) {
-                /* All exports (other than the self-export) have been
-                   destroyed; there should be no more in-progress ops
-                   by this point.*/
-                /* if we're not stopping, we didn't finish setup */
-                /* Precleanup stage 2,  do other type-specific
-                   cleanup requiring the self-export. */
-                err = obd_precleanup(obd, OBD_CLEANUP_SELF_EXP);
-                if (err)
-                        CERROR("Precleanup %s returned %d\n",
-                               obd->obd_name, err);
+                /* All exports have been destroyed; there should
+                   be no more in-progress ops by this point.*/
+
+                spin_lock(&obd->obd_self_export->exp_lock);
                 obd->obd_self_export->exp_flags |=
                         (obd->obd_fail ? OBD_OPT_FAILOVER : 0) |
                         (obd->obd_force ? OBD_OPT_FORCE : 0);
+                spin_unlock(&obd->obd_self_export->exp_lock);
+
                 /* note that we'll recurse into class_decref again */
                 class_unlink_export(obd->obd_self_export);
                 return;
@@ -516,7 +535,7 @@ int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
                 RETURN(-EINVAL);
         }
         if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
-            strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) && 
+            strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
             strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
                 CERROR("can't add connection on non-client dev\n");
                 RETURN(-EINVAL);
@@ -566,7 +585,7 @@ int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
 
 CFS_LIST_HEAD(lustre_profile_list);
 
-struct lustre_profile *class_get_profile(char * prof)
+struct lustre_profile *class_get_profile(const char * prof)
 {
         struct lustre_profile *lprof;
 
@@ -600,34 +619,34 @@ int class_add_profile(int proflen, char *prof, int osclen, char *osc,
         memcpy(lprof->lp_profile, prof, proflen);
 
         LASSERT(osclen == (strlen(osc) + 1));
-        OBD_ALLOC(lprof->lp_osc, osclen);
-        if (lprof->lp_osc == NULL)
+        OBD_ALLOC(lprof->lp_dt, osclen);
+        if (lprof->lp_dt == NULL)
                 GOTO(out, err = -ENOMEM);
-        memcpy(lprof->lp_osc, osc, osclen);
+        memcpy(lprof->lp_dt, osc, osclen);
 
         if (mdclen > 0) {
                 LASSERT(mdclen == (strlen(mdc) + 1));
-                OBD_ALLOC(lprof->lp_mdc, mdclen);
-                if (lprof->lp_mdc == NULL)
+                OBD_ALLOC(lprof->lp_md, mdclen);
+                if (lprof->lp_md == NULL)
                         GOTO(out, err = -ENOMEM);
-                memcpy(lprof->lp_mdc, mdc, mdclen);
+                memcpy(lprof->lp_md, mdc, mdclen);
         }
 
         list_add(&lprof->lp_list, &lustre_profile_list);
         RETURN(err);
 
 out:
-        if (lprof->lp_mdc)
-                OBD_FREE(lprof->lp_mdc, mdclen);
-        if (lprof->lp_osc)
-                OBD_FREE(lprof->lp_osc, osclen);
+        if (lprof->lp_md)
+                OBD_FREE(lprof->lp_md, mdclen);
+        if (lprof->lp_dt)
+                OBD_FREE(lprof->lp_dt, osclen);
         if (lprof->lp_profile)
                 OBD_FREE(lprof->lp_profile, proflen);
         OBD_FREE(lprof, sizeof(*lprof));        
         RETURN(err);
 }
 
-void class_del_profile(char *prof)
+void class_del_profile(const char *prof)
 {
         struct lustre_profile *lprof;
         ENTRY;
@@ -638,9 +657,9 @@ void class_del_profile(char *prof)
         if (lprof) {
                 list_del(&lprof->lp_list);
                 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
-                OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
-                if (lprof->lp_mdc)
-                        OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
+                OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
+                if (lprof->lp_md)
+                        OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
                 OBD_FREE(lprof, sizeof *lprof);
         }
         EXIT;
@@ -655,9 +674,9 @@ void class_del_profiles(void)
         list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
                 list_del(&lprof->lp_list);
                 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
-                OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
-                if (lprof->lp_mdc)
-                        OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
+                OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
+                if (lprof->lp_md)
+                        OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
                 OBD_FREE(lprof, sizeof *lprof);
         }
         EXIT;
@@ -731,7 +750,7 @@ int class_process_config(struct lustre_cfg *lcfg)
                 GOTO(out, err = 0);
         }
         case LCFG_SET_UPCALL: {
-                LCONSOLE_ERROR("recovery upcall is deprecated\n");
+                LCONSOLE_ERROR_MSG(0x15a, "recovery upcall is deprecated\n");
                 /* COMPAT_146 Don't fail on old configs */
                 GOTO(out, err = 0);
         }
@@ -739,7 +758,7 @@ int class_process_config(struct lustre_cfg *lcfg)
                 struct cfg_marker *marker;
                 marker = lustre_cfg_buf(lcfg, 1);
                 CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
-                      marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
+                       marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
                 GOTO(out, err = 0);
         }
         case LCFG_PARAM: {
@@ -809,7 +828,7 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
 #ifdef __KERNEL__
         struct lprocfs_vars *var;
         char *key, *sval;
-        int i, vallen;
+        int i, keylen, vallen;
         int matched = 0, j = 0;
         int rc = 0;
         ENTRY;
@@ -833,6 +852,7 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
                         /* continue parsing other params */
                         continue;
                 }
+                keylen = sval - key;
                 sval++;
                 vallen = strlen(sval);
                 matched = 0;
@@ -840,7 +860,8 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
                 /* Search proc entries */
                 while (lvars[j].name) {
                         var = &lvars[j];
-                        if (class_match_param(key, (char *)var->name, 0) == 0) {
+                        if (class_match_param(key, (char *)var->name, 0) == 0 &&
+                            keylen == strlen(var->name)) {
                                 matched++;
                                 rc = -EROFS;
                                 if (var->write_fptr) {
@@ -859,14 +880,14 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
                         j++;
                 }    
                 if (!matched) {
-                        CERROR("Unknown param %s\n", key);
-                        rc = -EINVAL;
-                        /* continue parsing other params */
+                        CERROR("%s: unknown param %s\n",
+                               (char *)lustre_cfg_string(lcfg, 0), key);
+                        /* rc = -EINVAL;       continue parsing other params */
                 } else {
                         LCONSOLE_INFO("%s.%.*s: set parameter %.*s=%s\n", 
-                                      lustre_cfg_buf(lcfg, 0),
-                                      strlen(prefix) - 1, prefix,
-                                      sval - key - 1, key, sval);
+                                      (char *)lustre_cfg_string(lcfg, 0),
+                                      (int)strlen(prefix) - 1, prefix,
+                                      (int)(sval - key - 1), key, sval);
                 }
         }
         
@@ -897,7 +918,7 @@ static int class_config_llog_handler(struct llog_handle * handle,
         char *cfg_buf = (char*) (rec + 1);
         int rc = 0;
         ENTRY;
-        
+
         //class_config_dump_handler(handle, rec, data);
 
         switch (rec->lrh_type) {
@@ -944,11 +965,12 @@ static int class_config_llog_handler(struct llog_handle * handle,
                 if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
                     !(clli->cfg_flags & CFG_F_MARKER) && 
                     (lcfg->lcfg_command != LCFG_MARKER)) {
-                        CWARN("Config not inside markers, ignoring! (%#x)\n", 
-                              clli->cfg_flags);
+                        CWARN("Config not inside markers, ignoring! "
+                              "(inst: %s, uuid: %s, flags: %#x)\n",
+                              clli->cfg_instance ? clli->cfg_instance : "<null>",
+                              clli->cfg_uuid.uuid, clli->cfg_flags);
                         clli->cfg_flags |= CFG_F_SKIP;
                 }
-
                 if (clli->cfg_flags & CFG_F_SKIP) {
                         CDEBUG(D_CONFIG, "skipping %#x\n",
                                clli->cfg_flags);
@@ -976,7 +998,7 @@ static int class_config_llog_handler(struct llog_handle * handle,
                                 lustre_cfg_string(lcfg, 0),
                                 clli->cfg_instance);
                         lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
-                        CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n", 
+                        CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
                                lcfg->lcfg_command, inst_name);
                 }
 
@@ -1056,6 +1078,7 @@ int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
 
         CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name, 
                cd.first_idx + 1, cd.last_idx, rc);
+
         if (cfg)
                 cfg->cfg_last_idx = cd.last_idx;
 
@@ -1109,7 +1132,7 @@ int class_config_dump_handler(struct llog_handle * handle,
                 if (lcfg->lcfg_command == LCFG_MARKER) {
                         struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
                         ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
-                                        marker->cm_step, marker->cm_flags, 
+                                        marker->cm_step, marker->cm_flags,
                                         marker->cm_tgtname, marker->cm_comment);
                 } else {
                         for (i = 0; i <  lcfg->lcfg_bufcount; i++) {