#include "pathlocks.hh" #include "util.hh" #include #include #include #include #include namespace nix { int openLockFile(const Path & path, bool create) { AutoCloseFD fd; fd = open(path.c_str(), O_RDWR | (create ? O_CREAT : 0), 0600); if (fd == -1 && (create || errno != ENOENT)) throw SysError(format("opening lock file `%1%'") % path); closeOnExec(fd); return fd.borrow(); } void deleteLockFile(const Path & path, int fd) { /* Get rid of the lock file. Have to be careful not to introduce races. Write a (meaningless) token to the file to indicate to other processes waiting on this lock that the lock is stale (deleted). */ unlink(path.c_str()); writeFull(fd, "d"); /* Note that the result of unlink() is ignored; removing the lock file is an optimisation, not a necessity. */ } bool lockFile(int fd, LockType lockType, bool wait) { struct flock lock; if (lockType == ltRead) lock.l_type = F_RDLCK; else
aboutsummaryrefslogtreecommitdiff
blob: 0d82e73d944b80f2d41a620af5db0e0a5c9c6769 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# This is a "service unit file" for the systemd init system to launch
# 'guix publish'.  Drop it in /etc/systemd/system or similar to have
# 'guix publish' automatically started.

[Unit]
Description=Publish the GNU Guix store
Requires=guix-daemon.service
PartOf=guix-daemon.service
After=guix-daemon.service

[Service]
ExecStart=@localstatedir@/guix/profiles/per-user/root/current-guix/bin/guix publish --user=nobody --port=8181
Environment='GUIX_LOCPATH=@localstatedir@/guix/profiles/per-user/root/guix-profile/lib/locale' LC_ALL=en_US.utf8
StandardOutput=journal
StandardError=journal

# Despite the name, this is rate-limited: a broken daemon will eventually fail.
Restart=always

# See <https://lists.gnu.org/archive/html/guix-devel/2016-04/msg00608.html>.
TasksMax=1024

[Install]
WantedBy=multi-user.target
PathLocks() { try { unlock(); } catch (...) { ignoreException(); } } void PathLocks::unlock() { foreach (list::iterator, i, fds) { if (deletePaths) deleteLockFile(i->second, i->first); lockedPaths.erase(i->second); if (close(i->first) == -1) printMsg(lvlError, format("error (ignored): cannot close lock file on `%1%'") % i->second); debug(format("lock released on `%1%'") % i->second); } fds.clear(); } void PathLocks::setDeletion(bool deletePaths) { this->deletePaths = deletePaths; } bool pathIsLockedByMe(const Path & path) { Path lockPath = path + ".lock"; return lockedPaths.find(lockPath) != lockedPaths.end(); } }