* Recheck that the data directory lock file still exists with expected * content. Return true if the lock file appears OK, false if it isn't. * * We call this periodically in the postmaster. The idea is that if the * lock file has been removed or replaced by another postmaster, we should * do a panic database shutdown. Therefore, we should return true if there * is any doubt: we do not wa
| 1572 | * (If there really is something wrong, we'll detect it on a future recheck.) |
| 1573 | */ |
| 1574 | bool |
| 1575 | RecheckDataDirLockFile(void) |
| 1576 | { |
| 1577 | int fd; |
| 1578 | int len; |
| 1579 | long file_pid; |
| 1580 | char buffer[BLCKSZ]; |
| 1581 | |
| 1582 | fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0); |
| 1583 | if (fd < 0) |
| 1584 | { |
| 1585 | /* |
| 1586 | * There are many foreseeable false-positive error conditions. For |
| 1587 | * safety, fail only on enumerated clearly-something-is-wrong |
| 1588 | * conditions. |
| 1589 | */ |
| 1590 | switch (errno) |
| 1591 | { |
| 1592 | case ENOENT: |
| 1593 | case ENOTDIR: |
| 1594 | /* disaster */ |
| 1595 | ereport(LOG, |
| 1596 | (errcode_for_file_access(), |
| 1597 | errmsg("could not open file \"%s\": %m", |
| 1598 | DIRECTORY_LOCK_FILE))); |
| 1599 | return false; |
| 1600 | default: |
| 1601 | /* non-fatal, at least for now */ |
| 1602 | ereport(LOG, |
| 1603 | (errcode_for_file_access(), |
| 1604 | errmsg("could not open file \"%s\": %m; continuing anyway", |
| 1605 | DIRECTORY_LOCK_FILE))); |
| 1606 | return true; |
| 1607 | } |
| 1608 | } |
| 1609 | pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ); |
| 1610 | len = read(fd, buffer, sizeof(buffer) - 1); |
| 1611 | pgstat_report_wait_end(); |
| 1612 | if (len < 0) |
| 1613 | { |
| 1614 | ereport(LOG, |
| 1615 | (errcode_for_file_access(), |
| 1616 | errmsg("could not read from file \"%s\": %m", |
| 1617 | DIRECTORY_LOCK_FILE))); |
| 1618 | close(fd); |
| 1619 | return true; /* treat read failure as nonfatal */ |
| 1620 | } |
| 1621 | buffer[len] = '\0'; |
| 1622 | close(fd); |
| 1623 | file_pid = atol(buffer); |
| 1624 | if (file_pid == getpid()) |
| 1625 | return true; /* all is well */ |
| 1626 | |
| 1627 | /* Trouble: someone's overwritten the lock file */ |
| 1628 | ereport(LOG, |
| 1629 | (errmsg("lock file \"%s\" contains wrong PID: %ld instead of %ld", |
| 1630 | DIRECTORY_LOCK_FILE, file_pid, (long) getpid()))); |
| 1631 | return false; |
no test coverage detected