.br
* Mount clients
.TP
+.BI \--nolocallogs
+Use configuration logs from the MGS, not local ones.
+.br
+There is feature that starts a target with a local copy of
+the config log in order to avoid a delay in communicating with
+the MGS and to load MGS log updates later on.
+However, that feature is not always useful.
+.br
+replace_nids changes config logs on the server side and local copies
+become invalid. --nolocallogs sets the nolocallogs mount flag,
+which causes the local copy of the config log to be ignored.
+The flag is reset once new logs are downloaded from MGS.
+.TP
.BI \--quota
Enable space accounting on old 2.x devices.
#define LMD_FLG_NO_PRECREATE 0x10000 /* do not allow OST object creation */
#define LMD_FLG_LOCAL_RECOV 0x20000 /* force recovery for local clients */
#define LMD_FLG_ABORT_RECOV_MDT 0x40000 /* Abort recovery between MDTs */
+#define LMD_FLG_NO_LOCAL_LOGS 0x80000 /* Use config logs from MGS */
#define lmd_is_client(x) ((x)->lmd_flags & LMD_FLG_CLIENT)
#define LDD_F_ERROR 0x4000
/** process at lctl conf_param */
#define LDD_F_PARAM2 0x8000
+/** the target shouldn't use local logs */
+#define LDD_F_NO_LOCAL_LOGS 0x10000
#define LDD_MAGIC 0x1dd00001
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.
} else if (strncmp(s1, "writeconf", 9) == 0) {
lmd->lmd_flags |= LMD_FLG_WRITECONF;
clear++;
+ } else if (strncmp(s1, "nolocallogs", 11) == 0) {
+ lmd->lmd_flags |= LMD_FLG_NO_LOCAL_LOGS;
+ clear++;
} else if (strncmp(s1, "update", 6) == 0) {
lmd->lmd_flags |= LMD_FLG_UPDATE;
clear++;
*/
lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_WRITECONF) ?
LDD_F_WRITECONF : 0;
+ lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_NO_LOCAL_LOGS) ?
+ LDD_F_NO_LOCAL_LOGS : 0;
lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_VIRGIN) ?
LDD_F_VIRGIN : 0;
lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_UPDATE) ?
}
run_test 127 "direct io overwrite on full ost"
+test_128()
+{
+ combined_mgs_mds && skip "need separate mgs device"
+ [ "$ost2_FSTYPE" == zfs ] && import_zpool ost2
+
+ format_ost 2
+ # Try to apply nolocallogs to the virgin OST. Should fail.
+ do_facet ost2 "$TUNEFS --nolocallogs $(ostdevname 2)" &&
+ error "nolocallogs should not be allowed on the virgin target"
+
+ setupall
+ stopall
+
+ [ "$ost1_FSTYPE" == zfs ] && import_zpool ost1
+ # Start OST without MGS (local configs)
+ do_facet ost1 "$TUNEFS --dryrun $(ostdevname 1)"
+ start_ost || error "unable to start OST1"
+ stop_ost || error "Unable to stop OST1"
+
+ [ "$ost1_FSTYPE" == zfs ] && import_zpool ost1
+ # Do not allow reading local configs, should fail
+ do_facet ost1 "$TUNEFS --nolocallogs $(ostdevname 1)" ||
+ error "Can not set nolocallogs"
+ start_ost && error "OST1 started, but should fail"
+
+ # Connect to MGS successfully, reset nolocallogs flag
+ [ "$ost1_FSTYPE" == zfs ] && import_zpool ost1
+ start_mgs || error "unable to start MGS"
+ start_ost || error "unable to start OST1"
+
+ do_facet ost1 "$TUNEFS --dryrun $(ostdevname 1)" | grep "nolocallogs" &&
+ error "nolocallogs expected to be reset"
+
+ stop_ost || error "Unable to stop OST1"
+}
+run_test 128 "Force using remote logs with --nolocallogs"
+
if ! combined_mgs_mds ; then
stop mgs
fi
"\t\t--erase-param <key>: erase all instances of a parameter\n"
"\t\t--erase-params: erase all old parameter settings\n"
"\t\t--writeconf: erase all config logs for this fs.\n"
+ "\t\t--nolocallogs: use logs from MGS, not local ones.\n"
"\t\t--quota: enable space accounting on old 2.x device.\n"
"\t\t--rename: rename the filesystem name\n"
#endif
printf("Lustre FS: %s\n", ldd->ldd_fsname);
printf("Mount type: %s\n", MT_STR(ldd));
printf("Flags: %#x\n", ldd->ldd_flags);
- printf(" (%s%s%s%s%s%s%s%s)\n",
+ printf(" (%s%s%s%s%s%s%s%s%s)\n",
IS_MDT(ldd) ? "MDT " : "",
IS_OST(ldd) ? "OST " : "",
IS_MGS(ldd) ? "MGS " : "",
ldd->ldd_flags & LDD_F_VIRGIN ? "first_time " : "",
ldd->ldd_flags & LDD_F_UPDATE ? "update " : "",
ldd->ldd_flags & LDD_F_WRITECONF ? "writeconf " : "",
- ldd->ldd_flags & LDD_F_NO_PRIMNODE ? "no_primnode " : "");
+ ldd->ldd_flags & LDD_F_NO_PRIMNODE ? "no_primnode " : "",
+ ldd->ldd_flags & LDD_F_NO_LOCAL_LOGS ? "nolocallogs " : "");
printf("Persistent mount opts: %s\n", ldd->ldd_mount_opts);
osd_print_ldd_params(mop);
if (ldd->ldd_userdata[0])
if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
if (!(flags & LDD_F_SV_ALL))
snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
- (flags & LDD_F_VIRGIN) ? ':' :
- ((flags & LDD_F_WRITECONF) ? '=' : '-'),
- (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
- index);
+ (flags & LDD_F_VIRGIN) ? ':' :
+ ((flags & LDD_F_WRITECONF) ? '=' :
+ ((flags & LDD_F_NO_LOCAL_LOGS) ? '+' : '-')),
+ (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
+ index);
} else if (flags & LDD_F_SV_TYPE_MGS) {
snprintf(name_buf, name_buf_size, "MGS");
} else {
{ .val = 'E', .name = "erase-param", .has_arg = required_argument},
{ .val = 'e', .name = "erase-params",
.has_arg = no_argument},
+ { .val = 'l', .name = "nolocallogs", .has_arg = no_argument},
{ .val = 'Q', .name = "quota", .has_arg = no_argument},
{ .val = 'R', .name = "rename", .has_arg = optional_argument},
{ .val = 'w', .name = "writeconf", .has_arg = no_argument},
#ifndef TUNEFS
"b:c:d:k:MOrR";
#else
- "E:eQR::w";
+ "E:elQR::w";
#endif
struct lustre_disk_data *ldd = &mop->mo_ldd;
char new_fsname[16] = { 0 };
case 'w':
ldd->ldd_flags |= LDD_F_WRITECONF;
break;
+ case 'l':
+ if (ldd->ldd_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
+ fprintf(stderr, "Can not apply nolocallogs to the target that was writeconfed or never been registered\n");
+ return EINVAL;
+ }
+ ldd->ldd_flags |= LDD_F_NO_LOCAL_LOGS;
+ break;
#endif /* !TUNEFS */
default:
if (opt != '?') {
}
strscpy(old_fsname, ldd->ldd_fsname, sizeof(ldd->ldd_fsname));
- ldd->ldd_flags &= ~(LDD_F_WRITECONF | LDD_F_VIRGIN);
+ ldd->ldd_flags &= ~(LDD_F_WRITECONF | LDD_F_VIRGIN |
+ LDD_F_NO_LOCAL_LOGS);
/* svname of the form lustre:OST1234 means never registered */
ret = strlen(ldd->ldd_svname);
} else if (ldd->ldd_svname[ret - 8] == '=') {
ldd->ldd_svname[ret - 8] = '-';
ldd->ldd_flags |= LDD_F_WRITECONF;
+ } else if (ldd->ldd_svname[ret - 8] == '+') {
+ ldd->ldd_svname[ret - 8] = '-';
+ ldd->ldd_flags |= LDD_F_NO_LOCAL_LOGS;
}
if (strstr(ldd->ldd_params, PARAM_MGSNODE))
goto out;
}
- if (check_mtab_entry(mop.mo_device, mop.mo_device, NULL, NULL))
+ if (check_mtab_entry(mop.mo_device, mop.mo_device, NULL, NULL)) {
+ fprintf(stderr, "%s: is currently mounted, exiting without any change\n",
+ mop.mo_device);
return EEXIST;
+ }
/* Create the loopback file */
if (mop.mo_flags & MO_IS_LOOP) {
(void)osd_label_lustre(&opts);
}
+ /* update svname with '+' to force remote logs */
+ if (ldd->ldd_flags & LDD_F_NO_LOCAL_LOGS) {
+ struct mount_opts opts;
+
+ opts.mo_ldd = *ldd;
+ opts.mo_source = mop.mo_device;
+ (void) osd_label_lustre(&opts);
+ }
+
/* Rename filesystem fsname */
if (mop.mo_flags & MO_RENAME) {
ret = osd_rename_fsname(&mop, old_fsname);
clear_update_ondisk(source, ldd);
/* Since we never rewrite ldd, ignore temp flags */
- ldd->ldd_flags &= ~(LDD_F_VIRGIN | LDD_F_WRITECONF);
+ ldd->ldd_flags &= ~(LDD_F_VIRGIN | LDD_F_WRITECONF |
+ LDD_F_NO_LOCAL_LOGS);
/* This is to make sure default options go first */
temp_options = strdup(options);
} else if (ldd->ldd_svname[rc - 8] == '=') {
ldd->ldd_svname[rc - 8] = '-';
ldd->ldd_flags |= LDD_F_WRITECONF;
+ } else if (ldd->ldd_svname[rc - 8] == '+') {
+ ldd->ldd_svname[rc - 8] = '-';
+ ldd->ldd_flags |= LDD_F_NO_LOCAL_LOGS;
}
}
/* backend osd type */
if (rc != 0)
return rc;
}
+ if (ldd->ldd_flags & LDD_F_NO_LOCAL_LOGS) {
+ rc = append_option(options, options_len, "nolocallogs", NULL);
+ if (rc != 0)
+ return rc;
+ }
if (ldd->ldd_flags & LDD_F_NO_PRIMNODE) {
rc = append_option(options, options_len, "noprimnode", NULL);
if (rc != 0)
if (mop->mo_nosvc)
return;
- if (mop->mo_ldd.ldd_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
+ if (mop->mo_ldd.ldd_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF |
+ LDD_F_NO_LOCAL_LOGS)) {
(void)osd_label_lustre(mop);
} else {
struct lustre_disk_data ldd;