X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=tools.py;h=776a8d48f94aa131fd990754383aea17437d5fc3;hb=2ea95268ac45ee96f6657ad424e3268ed915fc7e;hp=994089e1bb69fe5ab4ee43b35106d09b4c4a43e2;hpb=28de48d05b66c4e7826d959a3ad48e87e8f13ee4;p=nodemanager.git diff --git a/tools.py b/tools.py index 994089e..776a8d4 100644 --- a/tools.py +++ b/tools.py @@ -6,6 +6,7 @@ import os import pwd import tempfile import threading +import fcntl import logger @@ -34,7 +35,11 @@ def daemon(): os.chdir('/') os.umask(0) devnull = os.open(os.devnull, os.O_RDWR) - for fd in range(3): os.dup2(devnull, fd) + os.dup2(devnull, 0) + # xxx fixme - this is just to make sure that nothing gets stupidly lost - should use devnull + crashlog = os.open('/var/log/nm.daemon', os.O_RDWR | os.O_APPEND | os.O_CREAT, 0644) + os.dup2(crashlog, 1) + os.dup2(crashlog, 2) def fork_as(su, function, *args): """fork(), cd / to avoid keeping unused directories open, close all nonstandard file descriptors (to avoid capturing open sockets), fork() again (to avoid zombies) and call with arguments in the grandchild process. If is not None, set our group and user ids appropriately in the child process.""" @@ -43,9 +48,10 @@ def fork_as(su, function, *args): try: os.chdir('/') close_nonstandard_fds() - pw_ent = pwd.getpwnam(su) - os.setegid(pw_ent[3]) - os.seteuid(pw_ent[2]) + if su: + pw_ent = pwd.getpwnam(su) + os.setegid(pw_ent[3]) + os.seteuid(pw_ent[2]) child_pid = os.fork() if child_pid == 0: function(*args) except: @@ -84,3 +90,20 @@ def write_temp_file(do_write, mode=None, uidgid=None): try: do_write(f) finally: f.close() return temporary_filename + + +class NMLock: + def __init__(self, file): + logger.log("Lock %s initialized." % file, 2) + self.fd = os.open(file, os.O_RDWR|os.O_CREAT, 0600) + flags = fcntl.fcntl(self.fd, fcntl.F_GETFD) + flags |= fcntl.FD_CLOEXEC + fcntl.fcntl(self.fd, fcntl.F_SETFD, flags) + def __del__(self): + os.close(self.fd) + def acquire(self): + logger.log("Lock acquired.", 2) + fcntl.lockf(self.fd, fcntl.LOCK_SH) + def release(self): + logger.log("Lock released.", 2) + fcntl.lockf(self.fd, fcntl.LOCK_UN)