int rc;
ENTRY;
+ if (!exp)
+ RETURN(-EBADR);
+
CDEBUG(D_MGC, "Enqueue for %s (res %#llx)\n", cld->cld_logname,
cld->cld_resid.name[0]);
int pos = 0;
int rc = 0;
int off = 0;
+ unsigned long dynamic_nids;
ENTRY;
LASSERT(cfg->cfg_instance != 0);
LASSERT(ll_get_cfg_instance(cfg->cfg_sb) == cfg->cfg_instance);
+ /* get dynamic nids setting */
+ dynamic_nids = mgc->obd_dynamic_nids;
+
OBD_ALLOC(inst, PAGE_SIZE);
if (inst == NULL)
RETURN(-ENOMEM);
#endif /* HAVE_SERVER_SUPPORT */
}
- ++pos;
- buf = inst + pos;
+ ++pos;
+ buf = inst + pos;
bufsz = PAGE_SIZE - pos;
- while (datalen > 0) {
- int entry_len = sizeof(*entry);
- int is_ost, i;
- struct obd_device *obd;
- char *obdname;
- char *cname;
- char *params;
- char *uuid;
-
- rc = -EINVAL;
- if (datalen < sizeof(*entry))
- break;
-
- entry = (typeof(entry))(data + off);
-
- /* sanity check */
- if (entry->mne_nid_type != 0) /* only support type 0 for ipv4 */
- break;
- if (entry->mne_nid_count == 0) /* at least one nid entry */
- break;
- if (entry->mne_nid_size != sizeof(lnet_nid_t))
- break;
-
- entry_len += entry->mne_nid_count * entry->mne_nid_size;
- if (datalen < entry_len) /* must have entry_len at least */
- break;
+ while (datalen > 0) {
+ int entry_len = sizeof(*entry);
+ int is_ost;
+ struct obd_device *obd;
+ struct obd_import *imp;
+ char *obdname;
+ char *cname;
+ char *params;
+ char *uuid;
+
+ rc = -EINVAL;
+ if (datalen < sizeof(*entry))
+ break;
+
+ entry = (typeof(entry))(data + off);
+
+ /* sanity check */
+ if (entry->mne_nid_type != 0) /* only support type 0 for ipv4 */
+ break;
+ if (entry->mne_nid_count == 0) /* at least one nid entry */
+ break;
+ if (entry->mne_nid_size != sizeof(lnet_nid_t))
+ break;
+
+ entry_len += entry->mne_nid_count * entry->mne_nid_size;
+ if (datalen < entry_len) /* must have entry_len at least */
+ break;
/* Keep this swab for normal mixed endian handling. LU-1644 */
if (mne_swab)
if (entry->mne_length < entry_len)
break;
- off += entry->mne_length;
- datalen -= entry->mne_length;
- if (datalen < 0)
- break;
+ off += entry->mne_length;
+ datalen -= entry->mne_length;
+ if (datalen < 0)
+ break;
- if (entry->mne_version > max_version) {
- CERROR("entry index(%lld) is over max_index(%lld)\n",
- entry->mne_version, max_version);
- break;
- }
+ if (entry->mne_version > max_version) {
+ CERROR("entry index(%lld) is over max_index(%lld)\n",
+ entry->mne_version, max_version);
+ break;
+ }
- if (prev_version >= entry->mne_version) {
- CERROR("index unsorted, prev %lld, now %lld\n",
- prev_version, entry->mne_version);
- break;
- }
- prev_version = entry->mne_version;
+ if (prev_version >= entry->mne_version) {
+ CERROR("index unsorted, prev %lld, now %lld\n",
+ prev_version, entry->mne_version);
+ break;
+ }
+ prev_version = entry->mne_version;
- /*
- * Write a string with format "nid::instance" to
- * lustre/<osc|mdc>/<target>-<osc|mdc>-<instance>/import.
- */
+ /*
+ * Write a string with format "nid::instance" to
+ * lustre/<osc|mdc>/<target>-<osc|mdc>-<instance>/import.
+ */
- is_ost = entry->mne_type == LDD_F_SV_TYPE_OST;
- memset(buf, 0, bufsz);
- obdname = buf;
- pos = 0;
-
- /* lustre-OST0001-osc-<instance #> */
- strcpy(obdname, cld->cld_logname);
- cname = strrchr(obdname, '-');
- if (cname == NULL) {
- CERROR("mgc %s: invalid logname %s\n",
- mgc->obd_name, obdname);
- break;
- }
+ is_ost = entry->mne_type == LDD_F_SV_TYPE_OST;
+ memset(buf, 0, bufsz);
+ obdname = buf;
+ pos = 0;
+
+ /* lustre-OST0001-osc-<instance #> */
+ strcpy(obdname, cld->cld_logname);
+ cname = strrchr(obdname, '-');
+ if (cname == NULL) {
+ CERROR("mgc %s: invalid logname %s\n",
+ mgc->obd_name, obdname);
+ break;
+ }
- pos = cname - obdname;
- obdname[pos] = 0;
- pos += sprintf(obdname + pos, "-%s%04x",
- is_ost ? "OST" : "MDT", entry->mne_index);
+ pos = cname - obdname;
+ obdname[pos] = 0;
+ pos += sprintf(obdname + pos, "-%s%04x",
+ is_ost ? "OST" : "MDT", entry->mne_index);
- cname = is_ost ? "osc" : "mdc",
- pos += sprintf(obdname + pos, "-%s-%s", cname, inst);
- lustre_cfg_bufs_reset(&bufs, obdname);
+ cname = is_ost ? "osc" : "mdc",
+ pos += sprintf(obdname + pos, "-%s-%s", cname, inst);
+ lustre_cfg_bufs_reset(&bufs, obdname);
- /* find the obd by obdname */
- obd = class_name2obd(obdname);
- if (obd == NULL) {
- CDEBUG(D_INFO, "mgc %s: cannot find obdname %s\n",
- mgc->obd_name, obdname);
+ /* find the obd by obdname */
+ obd = class_name2obd(obdname);
+ if (obd == NULL) {
+ CDEBUG(D_INFO, "mgc %s: cannot find obdname %s\n",
+ mgc->obd_name, obdname);
rc = 0;
- /* this is a safe race, when the ost is starting up...*/
- continue;
- }
-
- /* osc.import = "connection=<Conn UUID>::<target instance>" */
- ++pos;
- params = buf + pos;
- pos += sprintf(params, "%s.import=%s", cname, "connection=");
- uuid = buf + pos;
+ /* this is a safe race, when the ost is starting up...*/
+ continue;
+ }
- down_read(&obd->u.cli.cl_sem);
- if (obd->u.cli.cl_import == NULL) {
+ /* osc.import = "connection=<Conn UUID>::<target instance>" */
+ ++pos;
+ params = buf + pos;
+ pos += sprintf(params, "%s.import=%s", cname, "connection=");
+ uuid = buf + pos;
+
+ with_imp_locked(obd, imp, rc) {
+ /* iterate all nids to find one */
+ /* find uuid by nid */
+ /* create import entries if they don't exist */
+ rc = client_import_add_nids_to_conn(
+ imp, entry->u.nids, entry->mne_nid_count,
+ (struct obd_uuid *)uuid);
+
+ if (rc == -ENOENT && dynamic_nids) {
+ /* create a new connection for this import */
+ char *primary_nid =
+ libcfs_nid2str(entry->u.nids[0]);
+ int prim_nid_len = strlen(primary_nid) + 1;
+ struct obd_uuid server_uuid;
+
+ if (prim_nid_len > UUID_MAX)
+ goto fail;
+ strncpy(server_uuid.uuid, primary_nid,
+ prim_nid_len);
+
+ CDEBUG(D_INFO, "Adding a connection for %s\n",
+ primary_nid);
+
+ rc = client_import_dyn_add_conn(
+ imp, &server_uuid, entry->u.nids[0], 1);
+ if (rc < 0) {
+ CERROR("%s: Failed to add new connection with NID '%s' to import: rc = %d\n",
+ obd->obd_name, primary_nid, rc);
+ goto fail;
+ }
+ rc = client_import_add_nids_to_conn(
+ imp, entry->u.nids,
+ entry->mne_nid_count,
+ (struct obd_uuid *)uuid);
+ if (rc < 0) {
+ CERROR("%s: failed to lookup UUID: rc = %d\n",
+ obd->obd_name, rc);
+ goto fail;
+ }
+ }
+fail:;
+ }
+ if (rc == -ENODEV) {
/* client does not connect to the OST yet */
- up_read(&obd->u.cli.cl_sem);
rc = 0;
continue;
}
- /* iterate all nids to find one */
- /* find uuid by nid */
- rc = -ENOENT;
- for (i = 0; i < entry->mne_nid_count; i++) {
- rc = client_import_find_conn(obd->u.cli.cl_import,
- entry->u.nids[i],
- (struct obd_uuid *)uuid);
- if (rc == 0)
- break;
+ if (rc < 0 && rc != -ENOSPC) {
+ CERROR("mgc: cannot find UUID by nid '%s': rc = %d\n",
+ libcfs_nid2str(entry->u.nids[0]), rc);
+ break;
}
- up_read(&obd->u.cli.cl_sem);
- if (rc < 0) {
- CERROR("mgc: cannot find uuid by nid %s\n",
- libcfs_nid2str(entry->u.nids[0]));
- break;
- }
+ CDEBUG(D_INFO, "Found UUID '%s' by NID '%s'\n",
+ uuid, libcfs_nid2str(entry->u.nids[0]));
- CDEBUG(D_INFO, "Find uuid %s by nid %s\n",
- uuid, libcfs_nid2str(entry->u.nids[0]));
+ pos += strlen(uuid);
+ pos += sprintf(buf + pos, "::%u", entry->mne_instance);
+ LASSERT(pos < bufsz);
- pos += strlen(uuid);
- pos += sprintf(buf + pos, "::%u", entry->mne_instance);
- LASSERT(pos < bufsz);
-
- lustre_cfg_bufs_set_string(&bufs, 1, params);
+ lustre_cfg_bufs_set_string(&bufs, 1, params);
OBD_ALLOC(lcfg, lustre_cfg_len(bufs.lcfg_bufcount,
bufs.lcfg_buflen));
lustre_cfg_init(lcfg, LCFG_PARAM, &bufs);
CDEBUG(D_INFO, "ir apply logs %lld/%lld for %s -> %s\n",
- prev_version, max_version, obdname, params);
+ prev_version, max_version, obdname, params);
- rc = class_process_config(lcfg);
+ rc = class_process_config(lcfg);
OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount,
lcfg->lcfg_buflens));
- if (rc)
- CDEBUG(D_INFO, "process config for %s error %d\n",
- obdname, rc);
+ if (rc)
+ CDEBUG(D_INFO, "process config for %s error %d\n",
+ obdname, rc);
- /* continue, even one with error */
- }
+ /* continue, even one with error */
+ }
OBD_FREE(inst, PAGE_SIZE);
RETURN(rc);
mgc_conn = class_exp2cliimp(cld->cld_mgcexp)->imp_connection;
/* don't need to get local config */
- if (cld_is_nodemap(cld) && (mgc_conn->c_peer.nid == LNET_NID_LO_0))
+ if (cld_is_nodemap(cld) && LNetIsPeerLocal(mgc_conn->c_peer.nid))
GOTO(out, rc = 0);
- /* allocate buffer for bulk transfer.
- * if this is the first time for this mgs to read logs,
- * CONFIG_READ_NRPAGES_INIT will be used since it will read all logs
- * once; otherwise, it only reads increment of logs, this should be
- * small and CONFIG_READ_NRPAGES will be used.
- */
- nrpages = CONFIG_READ_NRPAGES;
+ /* allocate buffer for bulk transfer.
+ * if this is the first time for this mgs to read logs,
+ * CONFIG_READ_NRPAGES_INIT will be used since it will read all logs
+ * once; otherwise, it only reads increment of logs, this should be
+ * small and CONFIG_READ_NRPAGES will be used.
+ */
+ nrpages = CONFIG_READ_NRPAGES;
if (cfg->cfg_last_idx == 0 || cld_is_nodemap(cld))
- nrpages = CONFIG_READ_NRPAGES_INIT;
+ nrpages = CONFIG_READ_NRPAGES_INIT;
- OBD_ALLOC(pages, sizeof(*pages) * nrpages);
- if (pages == NULL)
- GOTO(out, rc = -ENOMEM);
+ OBD_ALLOC_PTR_ARRAY(pages, nrpages);
+ if (pages == NULL)
+ GOTO(out, rc = -ENOMEM);
- for (i = 0; i < nrpages; i++) {
+ for (i = 0; i < nrpages; i++) {
pages[i] = alloc_page(GFP_KERNEL);
- if (pages[i] == NULL)
- GOTO(out, rc = -ENOMEM);
- }
+ if (pages[i] == NULL)
+ GOTO(out, rc = -ENOMEM);
+ }
again:
#ifdef HAVE_SERVER_SUPPORT
break;
__free_page(pages[i]);
}
- OBD_FREE(pages, sizeof(*pages) * nrpages);
+ OBD_FREE_PTR_ARRAY(pages, nrpages);
}
return rc;
}
cli->cl_mgc_configs_dir != NULL &&
lu2dt_dev(cli->cl_mgc_configs_dir->do_lu.lo_dev) ==
lsi->lsi_dt_dev) {
- if (!local_only && !lsi->lsi_dt_dev->dd_rdonly)
+ if (!local_only && !lsi->lsi_dt_dev->dd_rdonly) {
/* Only try to copy log if we have the lock. */
+ CDEBUG(D_INFO, "%s: copy local log %s\n",
+ mgc->obd_name, cld->cld_logname);
+
rc = mgc_llog_local_copy(env, mgc, ctxt, lctxt,
cld->cld_logname);
+ if (!rc)
+ lsi->lsi_flags &= ~LDD_F_NO_LOCAL_LOGS;
+ }
if (local_only || rc) {
+ if (unlikely(lsi->lsi_flags & LDD_F_NO_LOCAL_LOGS)
+ || rc) {
+ CWARN("%s: local log %s are not valid and/or remote logs are not accessbile rc = %d\n",
+ mgc->obd_name, cld->cld_logname, rc);
+ GOTO(out_pop, rc = -EIO);
+ }
+
if (strcmp(cld->cld_logname, PARAMS_FILENAME) != 0 &&
llog_is_empty(env, lctxt, cld->cld_logname)) {
- LCONSOLE_ERROR_MSG(0x13a, "Failed to get MGS "
- "log %s and no local copy."
- "\n", cld->cld_logname);
+ LCONSOLE_ERROR_MSG(0x13a, "Failed to get MGS log %s and no local copy.\n",
+ cld->cld_logname);
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",
- cld->cld_logname);
+ CDEBUG(D_MGC, "%s: Failed to get MGS log %s, using local copy for now, will try to update later.\n",
+ mgc->obd_name, cld->cld_logname);
rc = 0;
}
/* Now, whether we copied or not, start using the local llog.
static int __init mgc_init(void)
{
- return class_register_type(&mgc_obd_ops, NULL, false, NULL,
+ return class_register_type(&mgc_obd_ops, NULL, false,
LUSTRE_MGC_NAME, NULL);
}