python-libuuid
python-libuuid copied to clipboard
uuid1 creation doesn't close files - hits file descriptor limit
I have a daemon that calls uuid.uuid1() occassionally. It eventually hits the file descriptor limit because, as far as I can tell, /var/lib/libuuid/clock.txt is never closed:
lrwx------ 1 root root 64 Jul 11 18:27 304 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:25 305 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:25 306 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:27 307 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:25 308 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:27 309 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:25 31 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:25 310 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:27 311 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:25 312 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:25 313 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:27 314 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:25 315 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:25 316 -> /var/lib/libuuid/clock.txt
lrwx------ 1 root root 64 Jul 11 18:27 317 -> /var/lib/libuuid/clock.txt
I looked at libuuid, and found this function:
e2fsprogs-8b3114e\gen_uuid.c
static int get_clock(uint32_t *clock_high, uint32_t *clock_low,
uint16_t *ret_clock_seq, int *num)
{
THREAD_LOCAL int adjustment = 0;
THREAD_LOCAL struct timeval last = {0, 0};
THREAD_LOCAL int state_fd = -2;
THREAD_LOCAL FILE *state_f;
THREAD_LOCAL uint16_t clock_seq;
struct timeval tv;
struct flock fl;
uint64_t clock_reg;
mode_t save_umask;
int len;
if (state_fd == -2) {
save_umask = umask(0);
state_fd = open("/var/lib/libuuid/clock.txt",
O_RDWR|O_CREAT, 0660);
(void) umask(save_umask);
state_f = fdopen(state_fd, "r+");
if (!state_f) {
close(state_fd);
state_fd = -1;
}
}
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = 0;
if (state_fd >= 0) {
rewind(state_f);
while (fcntl(state_fd, F_SETLKW, &fl) < 0) {
if ((errno == EAGAIN) || (errno == EINTR))
continue;
fclose(state_f);
close(state_fd);
state_fd = -1;
break;
}
}
if (state_fd >= 0) {
unsigned int cl;
unsigned long tv1, tv2;
int a;
if (fscanf(state_f, "clock: %04x tv: %lu %lu adj: %d\n",
&cl, &tv1, &tv2, &a) == 4) {
clock_seq = cl & 0x3FFF;
last.tv_sec = tv1;
last.tv_usec = tv2;
adjustment = a;
}
}
if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
get_random_bytes(&clock_seq, sizeof(clock_seq));
clock_seq &= 0x3FFF;
gettimeofday(&last, 0);
last.tv_sec--;
}
try_again:
gettimeofday(&tv, 0);
if ((tv.tv_sec < last.tv_sec) ||
((tv.tv_sec == last.tv_sec) &&
(tv.tv_usec < last.tv_usec))) {
clock_seq = (clock_seq+1) & 0x3FFF;
adjustment = 0;
last = tv;
} else if ((tv.tv_sec == last.tv_sec) &&
(tv.tv_usec == last.tv_usec)) {
if (adjustment >= MAX_ADJUSTMENT)
goto try_again;
adjustment++;
} else {
adjustment = 0;
last = tv;
}
clock_reg = tv.tv_usec*10 + adjustment;
clock_reg += ((uint64_t) tv.tv_sec)*10000000;
clock_reg += (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
if (num && (*num > 1)) {
adjustment += *num - 1;
last.tv_usec += adjustment / 10;
adjustment = adjustment % 10;
last.tv_sec += last.tv_usec / 1000000;
last.tv_usec = last.tv_usec % 1000000;
}
if (state_fd > 0) {
rewind(state_f);
len = fprintf(state_f,
"clock: %04x tv: %016lu %08lu adj: %08d\n",
clock_seq, last.tv_sec, last.tv_usec, adjustment);
fflush(state_f);
if (ftruncate(state_fd, len) < 0) {
fprintf(state_f, " \n");
fflush(state_f);
}
rewind(state_f);
fl.l_type = F_UNLCK;
fcntl(state_fd, F_SETLK, &fl);
}
*clock_high = clock_reg >> 32;
*clock_low = clock_reg;
*ret_clock_seq = clock_seq;
return 0;
}
This doesn't seem the close the file descriptor state_fd - but I wanted another opinion. Does this make sense? Is it an issue with libuuid or with python, or am I doing something wrong...?
Apparently this is a known issue: http://comments.gmane.org/gmane.linux.utilities.util-linux-ng/4771 and there no no fix coming down the pipe. Perhaps this is worth a comment somewhere? I'm going to have to switch to another type of library code.