Whamcloud - gitweb
LU-3155 mgs: set_param -P option that sets value permanently
[fs/lustre-release.git] / lustre / mgc / mgc_request.c
index e503c1b..f91f8a1 100644 (file)
@@ -56,7 +56,7 @@ static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id,
 {
         __u64 resname = 0;
 
-        if (len > 8) {
+       if (len > sizeof(resname)) {
                 CERROR("name too long: %s\n", name);
                 return -EINVAL;
         }
@@ -75,7 +75,8 @@ static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id,
         case CONFIG_T_SPTLRPC:
                 resname = 0;
                 break;
-        case CONFIG_T_RECOVER:
+       case CONFIG_T_RECOVER:
+       case CONFIG_T_PARAMS:
                 resname = type;
                 break;
         default:
@@ -97,15 +98,18 @@ EXPORT_SYMBOL(mgc_fsname2resid);
 
 int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id, int type)
 {
-        char *name_end;
-        int len;
-
-        /* logname consists of "fsname-nodetype".
-         * e.g. "lustre-MDT0001", "SUN-000-client" */
-        name_end = strrchr(logname, '-');
-        LASSERT(name_end);
-        len = name_end - logname;
-        return mgc_name2resid(logname, len, res_id, type);
+       char *name_end;
+       int len;
+
+       /* logname consists of "fsname-nodetype".
+        * e.g. "lustre-MDT0001", "SUN-000-client"
+        * there is an exception: llog "params" */
+       name_end = strrchr(logname, '-');
+       if (!name_end)
+               len = strlen(logname);
+       else
+               len = name_end - logname;
+       return mgc_name2resid(logname, len, res_id, type);
 }
 
 /********************** config llog list **********************/
@@ -143,6 +147,8 @@ static void config_log_put(struct config_llog_data *cld)
                         config_log_put(cld->cld_recover);
                 if (cld->cld_sptlrpc)
                         config_log_put(cld->cld_sptlrpc);
+               if (cld->cld_params)
+                       config_log_put(cld->cld_params);
                 if (cld_is_sptlrpc(cld))
                         sptlrpc_conf_log_stop(cld->cld_logname);
 
@@ -278,6 +284,19 @@ static struct config_llog_data *config_recover_log_add(struct obd_device *obd,
         return cld;
 }
 
+static struct config_llog_data *config_params_log_add(struct obd_device *obd,
+       struct config_llog_instance *cfg, struct super_block *sb)
+{
+       struct config_llog_instance     lcfg = *cfg;
+       struct config_llog_data         *cld;
+
+       lcfg.cfg_instance = sb;
+
+       cld = do_config_log_add(obd, PARAMS_FILENAME, CONFIG_T_PARAMS,
+                               &lcfg, sb);
+
+       return cld;
+}
 
 /** Add this log to the list of active logs watched by an MGC.
  * Active means we're watching for updates.
@@ -288,12 +307,14 @@ static int config_log_add(struct obd_device *obd, char *logname,
                           struct config_llog_instance *cfg,
                           struct super_block *sb)
 {
-        struct lustre_sb_info *lsi = s2lsi(sb);
-        struct config_llog_data *cld;
-        struct config_llog_data *sptlrpc_cld;
-        char                     seclogname[32];
-        char                    *ptr;
-        ENTRY;
+       struct lustre_sb_info   *lsi = s2lsi(sb);
+       struct config_llog_data *cld;
+       struct config_llog_data *sptlrpc_cld;
+       struct config_llog_data *params_cld;
+       char                    seclogname[32];
+       char                    *ptr;
+       int                     rc;
+       ENTRY;
 
         CDEBUG(D_MGC, "adding config log %s:%p\n", logname, cfg->cfg_instance);
 
@@ -316,32 +337,49 @@ static int config_log_add(struct obd_device *obd, char *logname,
                                                 CONFIG_T_SPTLRPC, NULL, NULL);
                 if (IS_ERR(sptlrpc_cld)) {
                         CERROR("can't create sptlrpc log: %s\n", seclogname);
-                        RETURN(PTR_ERR(sptlrpc_cld));
+                       GOTO(out_err, rc = PTR_ERR(sptlrpc_cld));
                 }
         }
+       params_cld = config_params_log_add(obd, cfg, sb);
+       if (IS_ERR(params_cld)) {
+               rc = PTR_ERR(params_cld);
+               CERROR("%s: can't create params log: rc = %d\n",
+                      obd->obd_name, rc);
+               GOTO(out_err1, rc);
+       }
 
-        cld = do_config_log_add(obd, logname, CONFIG_T_CONFIG, cfg, sb);
-        if (IS_ERR(cld)) {
-                CERROR("can't create log: %s\n", logname);
-                config_log_put(sptlrpc_cld);
-                RETURN(PTR_ERR(cld));
-        }
+       cld = do_config_log_add(obd, logname, CONFIG_T_CONFIG, cfg, sb);
+       if (IS_ERR(cld)) {
+               CERROR("can't create log: %s\n", logname);
+               GOTO(out_err2, rc = PTR_ERR(cld));
+       }
 
-        cld->cld_sptlrpc = sptlrpc_cld;
+       cld->cld_sptlrpc = sptlrpc_cld;
+       cld->cld_params = params_cld;
 
         LASSERT(lsi->lsi_lmd);
         if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOIR)) {
                 struct config_llog_data *recover_cld;
                 *strrchr(seclogname, '-') = 0;
                 recover_cld = config_recover_log_add(obd, seclogname, cfg, sb);
-                if (IS_ERR(recover_cld)) {
-                        config_log_put(cld);
-                        RETURN(PTR_ERR(recover_cld));
-                }
-                cld->cld_recover = recover_cld;
-        }
+               if (IS_ERR(recover_cld))
+                       GOTO(out_err3, rc = PTR_ERR(recover_cld));
+               cld->cld_recover = recover_cld;
+       }
 
-        RETURN(0);
+       RETURN(0);
+
+out_err3:
+       config_log_put(cld);
+
+out_err2:
+       config_log_put(params_cld);
+
+out_err1:
+       config_log_put(sptlrpc_cld);
+
+out_err:
+       RETURN(rc);
 }
 
 DEFINE_MUTEX(llog_process_lock);
@@ -352,6 +390,7 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg)
 {
         struct config_llog_data *cld;
         struct config_llog_data *cld_sptlrpc = NULL;
+       struct config_llog_data *cld_params = NULL;
         struct config_llog_data *cld_recover = NULL;
         int rc = 0;
         ENTRY;
@@ -391,11 +430,20 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg)
        spin_lock(&config_list_lock);
        cld_sptlrpc = cld->cld_sptlrpc;
        cld->cld_sptlrpc = NULL;
+       cld_params = cld->cld_params;
+       cld->cld_params = NULL;
        spin_unlock(&config_list_lock);
 
         if (cld_sptlrpc)
                 config_log_put(cld_sptlrpc);
 
+       if (cld_params) {
+               mutex_lock(&cld_params->cld_lock);
+               cld_params->cld_stopping = 1;
+               mutex_unlock(&cld_params->cld_lock);
+               config_log_put(cld_params);
+       }
+
         /* drop the ref from the find */
         config_log_put(cld);
         /* drop the start ref */
@@ -527,8 +575,8 @@ static int mgc_requeue_thread(void *data)
                         cld_prev = cld;
 
                         cld->cld_lostlock = 0;
-                        if (likely(!stopped))
-                                do_requeue(cld);
+                       if (likely(!stopped))
+                               do_requeue(cld);
 
                        spin_lock(&config_list_lock);
                }
@@ -1706,7 +1754,7 @@ static int mgc_process_cfg_log(struct obd_device *mgc,
                                LCONSOLE_ERROR_MSG(0x13a, "Failed to get MGS "
                                                   "log %s and no local copy."
                                                   "\n", cld->cld_logname);
-                               GOTO(out_pop, rc = -ENOTCONN);
+                               GOTO(out_pop, rc = -ENOENT);
                        }
                        CDEBUG(D_MGC, "Failed to get MGS log %s, using local "
                               "copy for now, will try to update later.\n",
@@ -1908,6 +1956,19 @@ static int mgc_process_config(struct obd_device *obd, obd_count len, void *buf)
                         if (rc)
                                 CERROR("Cannot process recover llog %d\n", rc);
                 }
+
+               if (rc == 0 && cld->cld_params != NULL) {
+                       rc = mgc_process_log(obd, cld->cld_params);
+                       if (rc == -ENOENT) {
+                               CDEBUG(D_MGC, "There is no params"
+                                             "config file yet\n");
+                               rc = 0;
+                       }
+                       /* params log is optional */
+                       if (rc)
+                               CERROR("%s: can't process params llog: rc = %d\n",
+                                      obd->obd_name, rc);
+               }
                 config_log_put(cld);
 
                 break;