1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

config: use timestamp with nanosecond precision

Since kernel 2.6 we can use more precise timestamping,
so e.g. we could better recognize configs are slightly
older then generated .cache file.
This commit is contained in:
Zdenek Kabelac 2015-03-18 10:59:41 +01:00
parent 6606b1bff3
commit 1260b86b2b
5 changed files with 25 additions and 15 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.118 -
=================================
Measure configuration timestamps with nanoseconds when available.
Disable lvchange of major and minor of pool LVs.
Fix pvscan --cache to not scan and read ignored metadata areas on PVs.
Add After=iscsi-shutdown.service to blk-availability.service systemd unit.

View File

@ -1140,6 +1140,7 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache
struct dev_filter *filter = NULL, *filter_components[2] = {0};
struct stat st;
const struct dm_config_node *cn;
struct timespec ts, cts;
cmd->dump_filter = 0;
@ -1212,11 +1213,14 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache
*/
if (!find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL) &&
load_persistent_cache && !cmd->is_long_lived &&
!stat(dev_cache, &st) &&
(st.st_ctime > config_file_timestamp(cmd->cft)) &&
!persistent_filter_load(cmd->filter, NULL))
log_verbose("Failed to load existing device cache from %s",
dev_cache);
!stat(dev_cache, &st)) {
lvm_stat_ctim(&ts, &st);
cts = config_file_timestamp(cmd->cft);
if (timespeccmp(&ts, &cts, >) &&
!persistent_filter_load(cmd->filter, NULL))
log_verbose("Failed to load existing device cache from %s",
dev_cache);
}
return 1;
bad:

View File

@ -53,7 +53,7 @@ struct config_file {
struct config_source {
config_source_t type;
time_t timestamp;
struct timespec timestamp;
union {
struct config_file *file;
struct config_file *profile;
@ -173,7 +173,7 @@ int config_file_check(struct dm_config_tree *cft, const char **filename, struct
return 0;
}
cs->timestamp = info->st_ctime;
lvm_stat_ctim(&cs->timestamp, info);
cf->exists = 1;
cf->st_size = info->st_size;
@ -193,6 +193,7 @@ int config_file_changed(struct dm_config_tree *cft)
struct config_source *cs = dm_config_get_custom(cft);
struct config_file *cf;
struct stat info;
struct timespec ts;
if (cs->type != CONFIG_FILE) {
log_error(INTERNAL_ERROR "config_file_changed: expected file config source, "
@ -226,7 +227,9 @@ int config_file_changed(struct dm_config_tree *cft)
}
/* Unchanged? */
if (cs->timestamp == info.st_ctime && cf->st_size == info.st_size)
lvm_stat_ctim(&ts, &info);
if ((timespeccmp(&cs->timestamp, &ts, ==)) &&
cf->st_size == info.st_size)
return 0;
reload:
@ -594,7 +597,7 @@ int config_file_read(struct dm_config_tree *cft)
return r;
}
time_t config_file_timestamp(struct dm_config_tree *cft)
struct timespec config_file_timestamp(struct dm_config_tree *cft)
{
struct config_source *cs = dm_config_get_custom(cft);
return cs->timestamp;
@ -1473,7 +1476,7 @@ int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
cs = dm_config_get_custom(cft);
csn = dm_config_get_custom(newdata);
if (cs && csn && (cs->timestamp < csn->timestamp))
if (cs && csn && timespeccmp(&cs->timestamp, &csn->timestamp, <))
cs->timestamp = csn->timestamp;
return 1;

View File

@ -215,7 +215,7 @@ int config_write(struct dm_config_tree *cft, struct config_def_tree_spec *tree_s
struct dm_config_tree *config_def_create_tree(struct config_def_tree_spec *spec);
void config_destroy(struct dm_config_tree *cft);
time_t config_file_timestamp(struct dm_config_tree *cft);
struct timespec config_file_timestamp(struct dm_config_tree *cft);
int config_file_changed(struct dm_config_tree *cft);
int config_file_check(struct dm_config_tree *cft, const char **filename, struct stat *info);

View File

@ -22,7 +22,7 @@ struct pfilter {
char *file;
struct dm_hash_table *devices;
struct dev_filter *real;
time_t ctime;
struct timespec ctime;
struct dev_types *dt;
};
@ -106,7 +106,7 @@ int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out
}
if (!stat(pf->file, &info))
pf->ctime = info.st_ctime;
lvm_stat_ctim(&pf->ctime, &info);
else {
log_very_verbose("%s: stat failed: %s", pf->file,
strerror(errno));
@ -177,6 +177,7 @@ static int _persistent_filter_dump(struct dev_filter *f, int merge_existing)
struct pfilter *pf;
char *tmp_file;
struct stat info, info2;
struct timespec ts;
struct dm_config_tree *cft = NULL;
FILE *fp;
int lockfd;
@ -227,7 +228,8 @@ static int _persistent_filter_dump(struct dev_filter *f, int merge_existing)
/*
* If file contents changed since we loaded it, merge new contents
*/
if (merge_existing && info.st_ctime != pf->ctime)
lvm_stat_ctim(&ts, &info);
if (merge_existing && timespeccmp(&ts, &pf->ctime, !=))
/* Keep cft open to avoid losing lock */
persistent_filter_load(f, &cft);
@ -352,7 +354,7 @@ struct dev_filter *persistent_filter_create(struct dev_types *dt,
/* Only merge cache file before dumping it if it changed externally. */
if (!stat(pf->file, &info))
pf->ctime = info.st_ctime;
lvm_stat_ctim(&pf->ctime, &info);
f->passes_filter = _lookup_p;
f->destroy = _persistent_destroy;