+static int mgs_check_record_match(const struct lu_env *env,
+ struct llog_handle *llh,
+ struct llog_rec_hdr *rec, void *data)
+{
+ struct cfg_marker *mc_marker = data;
+ struct cfg_marker *marker;
+ struct lustre_cfg *lcfg = REC_DATA(rec);
+ int cfg_len = REC_DATA_LEN(rec);
+ int rc;
+ ENTRY;
+
+
+ if (rec->lrh_type != OBD_CFG_REC) {
+ CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
+ RETURN(-EINVAL);
+ }
+
+ rc = lustre_cfg_sanity_check(lcfg, cfg_len);
+ if (rc) {
+ CDEBUG(D_ERROR, "Insane cfg\n");
+ RETURN(rc);
+ }
+
+ /* We only care about markers */
+ if (lcfg->lcfg_command != LCFG_MARKER)
+ RETURN(0);
+
+ marker = lustre_cfg_buf(lcfg, 1);
+
+ if (marker->cm_flags & CM_SKIP)
+ RETURN(0);
+
+ if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
+ (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
+ /* Found a non-skipped marker match */
+ CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
+ rec->lrh_index, marker->cm_step,
+ marker->cm_flags, marker->cm_tgtname,
+ marker->cm_comment);
+ rc = LLOG_PROC_BREAK;
+ }
+
+ RETURN(rc);
+}
+
+/**
+ * Check an existing config log record with matching comment and device
+ * Return code:
+ * 0 - checked successfully,
+ * LLOG_PROC_BREAK - record matches
+ * negative - error
+ */
+static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
+ struct fs_db *fsdb, struct mgs_target_info *mti,
+ char *logname, char *devname, char *comment)
+{
+ struct llog_handle *loghandle;
+ struct llog_ctxt *ctxt;
+ struct cfg_marker *mc_marker;
+ int rc;
+
+ ENTRY;
+
+ LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
+ CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
+
+ ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
+ LASSERT(ctxt != NULL);
+ rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
+ if (rc < 0) {
+ if (rc == -ENOENT)
+ rc = 0;
+ GOTO(out_pop, rc);
+ }
+
+ rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
+ if (rc)
+ GOTO(out_close, rc);
+
+ if (llog_get_size(loghandle) <= 1)
+ GOTO(out_close, rc = 0);
+
+ OBD_ALLOC_PTR(mc_marker);
+ if (!mc_marker)
+ GOTO(out_close, rc = -ENOMEM);
+ if (strlcpy(mc_marker->cm_comment, comment,
+ sizeof(mc_marker->cm_comment)) >=
+ sizeof(mc_marker->cm_comment))
+ GOTO(out_free, rc = -E2BIG);
+ if (strlcpy(mc_marker->cm_tgtname, devname,
+ sizeof(mc_marker->cm_tgtname)) >=
+ sizeof(mc_marker->cm_tgtname))
+ GOTO(out_free, rc = -E2BIG);
+
+ rc = llog_process(env, loghandle, mgs_check_record_match,
+ (void *)mc_marker, NULL);
+
+out_free:
+ OBD_FREE_PTR(mc_marker);
+
+out_close:
+ llog_close(env, loghandle);
+out_pop:
+ if (rc && rc != LLOG_PROC_BREAK)
+ CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
+ mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
+ llog_ctxt_put(ctxt);
+ RETURN(rc);
+}
+