diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 04c2f672b..5f1e7330c 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -155,12 +155,13 @@ static int ongoing_create(struct lxc_container *c) if (ret < 0 || (size_t)ret >= len) return -1; - if (!file_exists(path)) - return 0; + fd = open(path, O_RDWR | O_CLOEXEC); + if (fd < 0) { + if (errno != ENOENT) + return -1; - fd = open(path, O_RDWR); - if (fd < 0) return 0; + } lk.l_type = F_WRLCK; lk.l_whence = SEEK_SET; @@ -170,8 +171,11 @@ static int ongoing_create(struct lxc_container *c) lk.l_pid = 0; ret = fcntl(fd, F_OFD_GETLK, &lk); - if (ret < 0 && errno == EINVAL) + if (ret < 0 && errno == EINVAL) { ret = flock(fd, LOCK_EX | LOCK_NB); + if (ret < 0 && errno == EWOULDBLOCK) + ret = 0; + } close(fd); @@ -198,7 +202,7 @@ static int create_partial(struct lxc_container *c) if (ret < 0 || (size_t)ret >= len) return -1; - fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0755); + fd = open(path, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0000); if (fd < 0) return -1; diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c index 8f533fa51..62fe2127f 100644 --- a/src/lxc/lxclock.c +++ b/src/lxc/lxclock.c @@ -96,9 +96,8 @@ static void unlock_mutex(pthread_mutex_t *l) static char *lxclock_name(const char *p, const char *n) { int ret; - int len; - char *dest; - char *rundir; + size_t len; + char *dest, *rundir; /* lockfile will be: * "/run" + "/lxc/lock/$lxcpath/$lxcname + '\0' if root @@ -107,20 +106,22 @@ static char *lxclock_name(const char *p, const char *n) */ /* length of "/lxc/lock/" + $lxcpath + "/" + "." + $lxcname + '\0' */ - len = strlen("/lxc/lock/") + strlen(n) + strlen(p) + 3; + len = (sizeof("/lxc/lock/") - 1) + strlen(n) + strlen(p) + 3; + rundir = get_rundir(); if (!rundir) return NULL; len += strlen(rundir); - if ((dest = malloc(len)) == NULL) { + dest = malloc(len); + if (!dest) { free(rundir); return NULL; } ret = snprintf(dest, len, "%s/lxc/lock/%s", rundir, p); - if (ret < 0 || ret >= len) { + if (ret < 0 || (size_t)ret >= len) { free(dest); free(rundir); return NULL; @@ -135,7 +136,7 @@ static char *lxclock_name(const char *p, const char *n) ret = snprintf(dest, len, "%s/lxc/lock/%s/.%s", rundir, p, n); free(rundir); - if (ret < 0 || ret >= len) { + if (ret < 0 || (size_t)ret >= len) { free(dest); return NULL; } @@ -145,15 +146,15 @@ static char *lxclock_name(const char *p, const char *n) static sem_t *lxc_new_unnamed_sem(void) { - sem_t *s; int ret; + sem_t *s; s = malloc(sizeof(*s)); if (!s) return NULL; ret = sem_init(s, 0, 1); - if (ret) { + if (ret < 0) { free(s); return NULL; } @@ -167,7 +168,7 @@ struct lxc_lock *lxc_newlock(const char *lxcpath, const char *name) l = malloc(sizeof(*l)); if (!l) - goto out; + goto on_error; if (!name) { l->type = LXC_LOCK_ANON_SEM; @@ -177,7 +178,7 @@ struct lxc_lock *lxc_newlock(const char *lxcpath, const char *name) l = NULL; } - goto out; + goto on_error; } l->type = LXC_LOCK_FLOCK; @@ -185,19 +186,19 @@ struct lxc_lock *lxc_newlock(const char *lxcpath, const char *name) if (!l->u.f.fname) { free(l); l = NULL; - goto out; + goto on_error; } l->u.f.fd = -1; -out: +on_error: return l; } int lxclock(struct lxc_lock *l, int timeout) { - int ret = -1, saved_errno = errno; struct flock lk; + int ret = -1, saved_errno = errno; switch(l->type) { case LXC_LOCK_ANON_SEM: @@ -208,9 +209,10 @@ int lxclock(struct lxc_lock *l, int timeout) } else { struct timespec ts; - if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { + ret = clock_gettime(CLOCK_REALTIME, &ts); + if (ret < 0) { ret = -2; - goto out; + goto on_error; } ts.tv_sec += timeout; @@ -218,25 +220,26 @@ int lxclock(struct lxc_lock *l, int timeout) if (ret < 0) saved_errno = errno; } + break; case LXC_LOCK_FLOCK: ret = -2; if (timeout) { - ERROR("Error: timeout not supported with flock"); - goto out; + ERROR("Timeouts are not supported with file locks"); + goto on_error; } if (!l->u.f.fname) { - ERROR("Error: filename not set for flock"); - goto out; + ERROR("No filename set for file lock"); + goto on_error; } if (l->u.f.fd == -1) { l->u.f.fd = open(l->u.f.fname, O_CREAT | O_RDWR | O_NOFOLLOW | O_CLOEXEC | O_NOCTTY, S_IWUSR | S_IRUSR); if (l->u.f.fd == -1) { - ERROR("Error opening %s", l->u.f.fname); + SYSERROR("Failed to open \"%s\"", l->u.f.fname); saved_errno = errno; - goto out; + goto on_error; } } @@ -251,27 +254,29 @@ int lxclock(struct lxc_lock *l, int timeout) ret = flock(l->u.f.fd, LOCK_EX); saved_errno = errno; } + break; } -out: +on_error: errno = saved_errno; return ret; } int lxcunlock(struct lxc_lock *l) { - int ret = 0, saved_errno = errno; struct flock lk; + int ret = 0, saved_errno = errno; - switch(l->type) { + switch (l->type) { case LXC_LOCK_ANON_SEM: - if (!l->u.sem) + if (!l->u.sem) { ret = -2; - else { + } else { ret = sem_post(l->u.sem); saved_errno = errno; } + break; case LXC_LOCK_FLOCK: if (l->u.f.fd != -1) { @@ -289,8 +294,10 @@ int lxcunlock(struct lxc_lock *l) close(l->u.f.fd); l->u.f.fd = -1; - } else + } else { ret = -2; + } + break; } @@ -317,6 +324,7 @@ void lxc_putlock(struct lxc_lock *l) free(l->u.sem); l->u.sem = NULL; } + break; case LXC_LOCK_FLOCK: if (l->u.f.fd != -1) { @@ -326,8 +334,10 @@ void lxc_putlock(struct lxc_lock *l) free(l->u.f.fname); l->u.f.fname = NULL; + break; } + free(l); } @@ -355,10 +365,12 @@ int container_disk_lock(struct lxc_container *c) { int ret; - if ((ret = lxclock(c->privlock, 0))) + ret = lxclock(c->privlock, 0); + if (ret < 0) return ret; - if ((ret = lxclock(c->slock, 0))) { + ret = lxclock(c->slock, 0); + if (ret < 0) { lxcunlock(c->privlock); return ret; }