From e2b53e16c60ba1e3bbbe59172c184e97f889326b Mon Sep 17 00:00:00 2001 From: Tiago Natel de Moura Date: Thu, 28 May 2020 14:57:41 +0100 Subject: Added "rootfs" feature. --- src/nxt_fs.c | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 src/nxt_fs.c (limited to 'src/nxt_fs.c') diff --git a/src/nxt_fs.c b/src/nxt_fs.c new file mode 100644 index 00000000..fe271802 --- /dev/null +++ b/src/nxt_fs.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) NGINX, Inc. + */ + +#include + +#if (NXT_HAVE_FREEBSD_NMOUNT) +#include +#include +#endif + + +static nxt_int_t nxt_fs_mkdir(const u_char *dir, mode_t mode); + + +#if (NXT_HAVE_LINUX_MOUNT) + +nxt_int_t +nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt) +{ + int rc; + + rc = mount((const char *) mnt->src, (const char *) mnt->dst, + (const char *) mnt->fstype, mnt->flags, mnt->data); + + if (nxt_slow_path(rc < 0)) { + nxt_alert(task, "mount(\"%s\", \"%s\", \"%s\", %d, \"%s\") %E", + mnt->src, mnt->dst, mnt->fstype, mnt->flags, mnt->data, + nxt_errno); + + return NXT_ERROR; + } + + return NXT_OK; +} + + +#elif (NXT_HAVE_FREEBSD_NMOUNT) + +nxt_int_t +nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt) +{ + const char *fstype; + uint8_t is_bind, is_proc; + struct iovec iov[8]; + char errmsg[256]; + + is_bind = nxt_strncmp(mnt->fstype, "bind", 4) == 0; + is_proc = nxt_strncmp(mnt->fstype, "proc", 4) == 0; + + if (nxt_slow_path(!is_bind && !is_proc)) { + nxt_alert(task, "mount type \"%s\" not implemented.", mnt->fstype); + return NXT_ERROR; + } + + if (is_bind) { + fstype = "nullfs"; + + } else { + fstype = "procfs"; + } + + iov[0].iov_base = (void *) "fstype"; + iov[0].iov_len = 7; + iov[1].iov_base = (void *) fstype; + iov[1].iov_len = strlen(fstype) + 1; + iov[2].iov_base = (void *) "fspath"; + iov[2].iov_len = 7; + iov[3].iov_base = (void *) mnt->dst; + iov[3].iov_len = nxt_strlen(mnt->dst) + 1; + iov[4].iov_base = (void *) "target"; + iov[4].iov_len = 7; + iov[5].iov_base = (void *) mnt->src; + iov[5].iov_len = nxt_strlen(mnt->src) + 1; + iov[6].iov_base = (void *) "errmsg"; + iov[6].iov_len = 7; + iov[7].iov_base = (void *) errmsg; + iov[7].iov_len = sizeof(errmsg); + + if (nxt_slow_path(nmount(iov, 8, 0) < 0)) { + nxt_alert(task, "nmount(%p, 8, 0) %s", errmsg); + return NXT_ERROR; + } + + return NXT_OK; +} + +#endif + + +#if (NXT_HAVE_LINUX_UMOUNT2) + +void +nxt_fs_unmount(const u_char *path) +{ + if (nxt_slow_path(umount2((const char *) path, MNT_DETACH) < 0)) { + nxt_thread_log_error(NXT_LOG_WARN, "umount2(%s, MNT_DETACH) %E", + path, nxt_errno); + } +} + +#elif (NXT_HAVE_UNMOUNT) + +void +nxt_fs_unmount(const u_char *path) +{ + if (nxt_slow_path(unmount((const char *) path, MNT_FORCE) < 0)) { + nxt_thread_log_error(NXT_LOG_WARN, "unmount(%s) %E", path, nxt_errno); + } +} + +#endif + + +nxt_int_t +nxt_fs_mkdir_all(const u_char *dir, mode_t mode) +{ + char *start, *end, *dst; + size_t dirlen; + char path[PATH_MAX]; + + dirlen = nxt_strlen(dir); + + nxt_assert(dirlen < PATH_MAX && dirlen > 1 && dir[0] == '/'); + + dst = path; + start = end = (char *) dir; + + while (*start != '\0') { + if (*start == '/') { + *dst++ = *start++; + } + + end = strchr(start, '/'); + if (end == NULL) { + end = ((char *)dir + dirlen); + } + + dst = nxt_cpymem(dst, start, end - start); + *dst = '\0'; + + if (nxt_slow_path(nxt_fs_mkdir((u_char *) path, mode) != NXT_OK + && nxt_errno != EEXIST)) + { + return NXT_ERROR; + } + + start = end; + } + + return NXT_OK; +} + + +static nxt_int_t +nxt_fs_mkdir(const u_char *dir, mode_t mode) +{ + if (nxt_fast_path(mkdir((const char *) dir, mode) == 0)) { + return NXT_OK; + } + + return NXT_ERROR; +} -- cgit