Skip Menu |
 

Subject: profile writes may not be immediately detected within same process
Download (untitled) / with headers
text/plain 1.6KiB
The attached test program, run with the pathname of an empty file, does
the following:

1. Open prof1 to a given filename
2. Open prof2 to the same filename, add a relation, and close it
3. Open prof3 to the same filename and try to read it

If steps 2 and 3 occur within the same clock second, step 3 won't see
the change from step 2. What happens under the covers is:

1. When prof1 is created, we read the file and populate g_shared_trees
with a prf_data_t object for the filename, with refcount 1. The
last_stat field of the prf_data_t object is set to the current time.

2a. When prof2 is created, we reuse the same prf_data_t object, so it
now has refcount 2. If the clock has advanced from step 1, we re-stat
the file, re-read it if it changed, and set last_stat to the current
time.

2b. When we add a relation to prof2, prof_set.c:rw_setup() is invoked.
This function creates a fresh prf_data_t object which is not part of
g_shared_trees, and alters prof2 to point to the new object. The old
shared object is dereferenced, but because prof1 is still open, its
refcount is still positive, so it is not destroyed and still has the
current time as last_stat.

2c. When prof2 is released, its contents are written out to the file and
the new private prf_data_t object is destroyed. The shared object for
the file in g_shared_trees is not touched in this step.

3. When prof3 is created, we reuse the prf_data_t object from step 1.
Since its last_stat field still has the current time from step 2a, we do
not check to see if the file was updated, and therefore do not read the
new contents with the relation added in step 2b.
Download proftest.c
text/x-csrc 901B
#include <stdio.h>
#include <stdlib.h>
#include <profile.h>
#include <com_err.h>

int
main(int argc, char **argv)
{
profile_t prof1, prof2, prof3;
const_profile_filespec_t *files = (const_profile_filespec_t *)(argv + 1);
const char *names[] = { "section", "key", NULL };
char **values;
long status;

if (argc != 2)
abort();

if (profile_init(files, &prof1))
abort();

profile_init(files, &prof2);
profile_add_relation(prof2, names, "value");
profile_release(prof2);

profile_init(files, &prof3);
status = profile_get_values(prof3, names, &values);
if (status == 0 && strcmp(values[0], "value") == 0)
printf("Successfully read from prof3\n");
else if (status == PROF_NO_RELATION)
printf("Could not read from prof3\n");
else
abort();
profile_free_list(values);
profile_release(prof3);

profile_release(prof1);
return 0;
}
From: ghudson@mit.edu
Subject: git commit

Always stat profile files after reopening them

Some applications write a profile file and then immediately use it via
a krb5_context. If we have a cached copy of the profile we wrote,
make sure to update it by forcing a stat when we reuse an existing
prf_data_t object.

[ghudson@mit.edu: commit message]

https://github.com/krb5/krb5/commit/53d6d0d64e96b84b57b7446a787e683312e2a529
Author: Will Fiveash <will.fiveash@oracle.com>
Committer: Greg Hudson <ghudson@mit.edu>
Commit: 53d6d0d64e96b84b57b7446a787e683312e2a529
Branch: master
src/util/profile/prof_file.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)