Блокировка и удаление файла - PullRequest
0 голосов
/ 16 декабря 2009

У меня следующая проблема. Я хочу создать хранилище сеансов на основе файловой системы, в котором данные каждого сеанса хранятся в простом файле с именами идентификаторов сеансов.

Я хочу следующий API: write(sid,data,timeout), read(sid,data,timeout), remove(sid) где sid == имя файла, также я хочу иметь какой-то GC, который может удалить все тайм-ауты сеансов.

Довольно простая задача, если вы работаете с одним процессом, но абсолютно не тривиальная при работе с несколькими процессами или даже над NFS.

Самое простое решение, о котором я думал, было:

write/read:
   fd=open(file_name,O_CREAT | O_RDWR); // create a new file or use exsting
   fcntl_lock_file(fd)
   save data to fd/read data from fd
   fcntl_unlock_file(fd)
   close(fd)

GC:
   fd=open(file_name,O_RDWR);
   fcntl_lock_file(fd)
   if(timed_out)
      unlink(file_name)
   fcntl_unlock_file(fd)
   close(fd)

Самая большая проблема заключается в том, что удаление файлов работает с именами файлов, а блокировки файлов работают с файлами. дескрипторы. Таким образом, вышесказанное не будет работать в следующем сценарии:

GC - open,
write - open
GC - lock, unlink, unlock, close // file still exists because held by write
write - lock, write, unlock, close // file removed

У кого-нибудь есть идеи, как решить эту проблему? Есть ли какие-нибудь хитрости, которые позволяют совмещать блокировку файлов и удаление файлов или выполнять операции с атомарными файлами?

Примечания:

  • Я не хочу использовать базу данных,
  • ищу решение для Unix
  • Решение должно работать со стандартными вызовами POSIX, такими как fcnl, open, close, unlink

Спасибо.

Очистка основная проблема заключается в том, что операция с файлами (имена - отсоединение) должна выполняться атомарно с операцией файловых дескрипторов - блокировка:

  • открыть, отменить связь - работа с файлами
  • fnctl - работа над дескрипторами

1 Ответ

1 голос
/ 16 декабря 2009

Разве это не сработает?

write/read:
   fd=open(file_name,O_CREAT | O_RDWR); // create a new file or use exsting
   fcntl_lock_file(fd)
   if stat(file_name).{st_dev, st_ino} != fstat(fd).{st_dev, st_ino}
       unlock, close, retry
   save data to fd/read data from fd
   fcntl_unlock_file(fd)
   close(fd)

Если stat завершается неудачно с EEXIST (имя файла не существует) или показывает, что текущий файл не совпадает с тем, который вы открыли, залог.

...