* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define _GNU_SOURCE
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <sys/mount.h>
#include <sys/prctl.h>
-#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <sys/wait.h>
+#include <unistd.h>
+#include "config.h"
#include "log.h"
#include "nbd.h"
#include "parse.h"
#include "storage.h"
#include "storage_utils.h"
+#include "syscall_wrappers.h"
#include "utils.h"
#ifndef HAVE_STRLCPY
const char *src;
src = lxc_storage_get_path(bdev->src, bdev->type);
- fd = open(src, O_RDONLY);
- if (fd < 0)
+
+ fd = open(src, O_RDONLY | O_CLOEXEC);
+ if (fd < 0) {
+ SYSERROR("Failed to open \"%s\"", src);
return -1;
+ }
/* size of device in bytes */
ret = ioctl(fd, BLKGETSIZE64, size);
+ if (ret < 0)
+ SYSERROR("Failed to get block size of dev-src");
+
close(fd);
return ret;
}
FILE *f;
char *sp1, *sp2, *sp3;
const char *l, *srcdev;
- char devpath[MAXPATHLEN];
+ char devpath[PATH_MAX];
char *line = NULL;
if (!bdev || !bdev->src || !bdev->dest)
srcdev = lxc_storage_get_path(bdev->src, bdev->type);
ret = pipe(p);
- if (ret < 0)
+ if (ret < 0) {
+ SYSERROR("Failed to create pipe");
return -1;
+ }
- if ((pid = fork()) < 0)
+ pid = fork();
+ if (pid < 0) {
+ SYSERROR("Failed to fork process");
return -1;
+ }
if (pid > 0) {
int status;
ssize_t ret;
ret = stat(path, &sbuf);
- if (ret < 0)
+ if (ret < 0) {
+ SYSERROR("Failed to get status of file - \"%s\"", path);
return NULL;
+ }
if (!S_ISLNK(sbuf.st_mode))
return path;
- ret = readlink(path, dest, MAXPATHLEN);
+ ret = readlink(path, dest, PATH_MAX);
if (ret < 0) {
SYSERROR("error reading link %s", path);
return NULL;
- } else if (ret >= MAXPATHLEN) {
+ } else if (ret >= PATH_MAX) {
ERROR("link in %s too long", path);
return NULL;
}
return false;
}
+uint64_t get_fssize(char *s)
+{
+ uint64_t ret;
+ char *end;
+
+ ret = strtoull(s, &end, 0);
+ if (end == s) {
+ ERROR("Invalid blockdev size '%s', using default size", s);
+ return 0;
+ }
+
+ while (isblank(*end))
+ end++;
+
+ if (*end == '\0') {
+ ret *= 1024ULL * 1024ULL; /* MB by default */
+ } else if (*end == 'b' || *end == 'B') {
+ ret *= 1ULL;
+ } else if (*end == 'k' || *end == 'K') {
+ ret *= 1024ULL;
+ } else if (*end == 'm' || *end == 'M') {
+ ret *= 1024ULL * 1024ULL;
+ } else if (*end == 'g' || *end == 'G') {
+ ret *= 1024ULL * 1024ULL * 1024ULL;
+ } else if (*end == 't' || *end == 'T') {
+ ret *= 1024ULL * 1024ULL * 1024ULL * 1024ULL;
+ } else {
+ ERROR("Invalid blockdev unit size '%c' in '%s', using default size", *end, s);
+ return 0;
+ }
+
+ return ret;
+}
+
bool is_valid_storage_type(const char *type)
{
if (strcmp(type, "dir") == 0 ||
struct lxc_conf *conf = data;
if (setgid(0) < 0) {
- ERROR("Failed to setgid to 0");
+ SYSERROR("Failed to setgid to 0");
return -1;
}
if (setgroups(0, NULL) < 0)
- WARN("Failed to clear groups");
+ SYSWARN("Failed to clear groups");
if (setuid(0) < 0) {
- ERROR("Failed to setuid to 0");
+ SYSERROR("Failed to setuid to 0");
return -1;
}
- if (!storage_destroy(conf))
+ if (!storage_destroy(conf)) {
+ ERROR("Failed to destroy storage");
return -1;
+ }
return 0;
}