Как/var/lib/dpkg/lock работает?

Просто выход из ада:

find . -regex '.*.\(m\|sh\)

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

3
09.04.2013, 02:54
2 ответа

Я не знаю наверняка, но это, скорее всего, реализовано через flock(). flock() системный вызов создает консультацию, соединяют файл. Если другое приложение попытается достигнуть блокировки на файле, то ядро заблокируется, пока первоначальной блокировки не не стало, или возвратиться EWOULDBLOCK если LOCK_NB опция дана. Этот механизм блокировки позволил бы файлу блокировки использоваться, не удаляя и воссоздавая его.

Обновление: Проверенный источник и проверенный, что это - консультативная блокировка, но это не использует flock() непосредственно. fcntl используется:

enquiry.c:

        if (modstatdb_is_locked())
          puts(_(
"Another process has locked the database for writing, and might currently be\n"
"modifying it, some of the following problems might just be due to that.\n"));
        head_running = true;
      }

dbmodify.c:

modstatdb_is_locked(void)
{
  int lockfd;
  bool locked;

  if (dblockfd == -1) {
    lockfd = open(lockfile, O_RDONLY);
    if (lockfd == -1)
      ohshite(_("unable to open lock file %s for testing"), lockfile);
  } else {
    lockfd = dblockfd;
  }

  locked = file_is_locked(lockfd, lockfile);

  /* We only close the file if there was no lock open, otherwise we would
   * release the existing lock on close. */
  if (dblockfd == -1)
    close(lockfd);

  return locked;
}

file.c:

file_is_locked(int lockfd, const char *filename)
{
    struct flock fl;

    file_lock_setup(&fl, F_WRLCK);

    if (fcntl(lockfd, F_GETLK, &fl) == -1)
        ohshit(_("unable to check file '%s' lock status"), filename);

    if (fl.l_type == F_WRLCK && fl.l_pid != getpid())
        return true;
    else
        return false;
}

dpkg.h:

#define LOCKFILE          "lock"

От fcntl страница справочника:

   Advisory locking
       F_GETLK,  F_SETLK  and  F_SETLKW  are  used to acquire, release, and test for the existence of record locks (also known as file-segment or file-region locks).  The third
       argument, lock, is a pointer to a structure that has at least the following fields (in unspecified order).
6
27.01.2020, 21:14
  • 1
    я попробовал это, но это, кажется, не имеет место. Я вручную захватил монопольную блокировку на файле, но dpkg, все еще управляемый обычно. –  Patrick 08.04.2013, 19:13
  • 2
    @Patrick I видит в исходном коде, что действительно на самом деле звонит flock() на файле блокировки в dbmodify.c. –  jordanm 08.04.2013, 19:18
  • 3
    @patrick lockfile является "блокировкой", не базой данных. –  jordanm 08.04.2013, 19:27
  • 4
    затем, почему делает flock -x /var/lib/dpkg/lock dpkg -r somepackage работа? –  Patrick 08.04.2013, 19:30
  • 5
    @Patrick блокировка не слоняется поблизости после выходов процесса вызывающей стороны. –  jordanm 08.04.2013, 19:34

Как я вижу, dpkg блокирует файл /var/lib/dpkg/lockс помощью lockf(3 ), который в свою очередь использует fcntl(2 ).

$ sudo strace dpkg -r somepackage 2>&1 |
> grep F_SETLKW
fcntl64(5, F_SETLKW64, {l_type=F_WRLCK, l_whence=SEEK_SET, l_start=0, l_len=0}) = 0

Это означает, что вы не можете заблокировать файл из оболочки, используя flock(1 ), потому что это вызывает flock(2 ), что во многих системах не взаимодействует с замком fnctl .

$ sudo strace flock -x /var/lib/dpkg/lock 2>&1 |
> grep 'flock('
flock(3, LOCK_EX)

Однако вы можете заблокировать файл с помощью программы с -блокировкой -ex или этого скрипта Python , оба из которых получают совместимую блокировку.

0
27.01.2020, 21:14

Теги

Похожие вопросы