1 /* 2 * Copyright (C) NGINX, Inc. 3 */ 4 5 #include <nxt_main.h> 6 7 #if (NXT_HAVE_FREEBSD_NMOUNT) 8 #include <sys/param.h> 9 #include <sys/uio.h> 10 #endif 11 12 13 static nxt_int_t nxt_fs_mkdir(const u_char *dir, mode_t mode); 14 15 16 #if (NXT_HAVE_LINUX_MOUNT) 17 18 nxt_int_t 19 nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt) 20 { 21 int rc; 22 23 rc = mount((const char *) mnt->src, (const char *) mnt->dst, 24 (const char *) mnt->fstype, mnt->flags, mnt->data); 25 26 if (nxt_slow_path(rc < 0)) { 27 nxt_alert(task, "mount(\"%s\", \"%s\", \"%s\", %d, \"%s\") %E", 28 mnt->src, mnt->dst, mnt->fstype, mnt->flags, mnt->data, 29 nxt_errno); 30 31 return NXT_ERROR; 32 } 33 34 return NXT_OK; 35 } 36 37 38 #elif (NXT_HAVE_FREEBSD_NMOUNT) 39 40 nxt_int_t 41 nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt) 42 { 43 u_char *data, *p, *end; 44 size_t iovlen; 45 nxt_int_t ret; 46 const char *fstype; 47 struct iovec iov[128]; 48 char errmsg[256]; 49 50 if (nxt_strncmp(mnt->fstype, "bind", 4) == 0) { 51 fstype = "nullfs"; 52 53 } else if (nxt_strncmp(mnt->fstype, "proc", 4) == 0) { 54 fstype = "procfs"; 55 56 } else if (nxt_strncmp(mnt->fstype, "tmpfs", 5) == 0) { 57 fstype = "tmpfs"; 58 59 } else { 60 nxt_alert(task, "mount type \"%s\" not implemented.", mnt->fstype); 61 return NXT_ERROR; 62 } 63 64 iov[0].iov_base = (void *) "fstype"; 65 iov[0].iov_len = 7; 66 iov[1].iov_base = (void *) fstype; 67 iov[1].iov_len = nxt_strlen(fstype) + 1; 68 iov[2].iov_base = (void *) "fspath"; 69 iov[2].iov_len = 7; 70 iov[3].iov_base = (void *) mnt->dst; 71 iov[3].iov_len = nxt_strlen(mnt->dst) + 1; 72 iov[4].iov_base = (void *) "target"; 73 iov[4].iov_len = 7; 74 iov[5].iov_base = (void *) mnt->src; 75 iov[5].iov_len = nxt_strlen(mnt->src) + 1; 76 iov[6].iov_base = (void *) "errmsg"; 77 iov[6].iov_len = 7; 78 iov[7].iov_base = (void *) errmsg; 79 iov[7].iov_len = sizeof(errmsg); 80 81 iovlen = 8; 82 83 data = NULL; 84 85 if (mnt->data != NULL) { 86 data = (u_char *) nxt_strdup(mnt->data); 87 if (nxt_slow_path(data == NULL)) { 88 return NXT_ERROR; 89 } 90 91 end = data - 1; 92 93 do { 94 p = end + 1; 95 end = nxt_strchr(p, '='); 96 if (end == NULL) { 97 break; 98 } 99 100 *end = '\0'; 101 102 iov[iovlen++].iov_base = (void *) p; 103 iov[iovlen++].iov_len = (end - p) + 1; 104 105 p = end + 1; 106 107 end = nxt_strchr(p, ','); 108 if (end != NULL) { 109 *end = '\0'; 110 } 111 112 iov[iovlen++].iov_base = (void *) p; 113 iov[iovlen++].iov_len = nxt_strlen(p) + 1; 114 115 } while (end != NULL && nxt_nitems(iov) > (iovlen + 2)); 116 } 117 118 ret = NXT_OK; 119 120 if (nxt_slow_path(nmount(iov, iovlen, 0) < 0)) { 121 nxt_alert(task, "nmount(%p, %d, 0) %s", iov, iovlen, errmsg); 122 ret = NXT_ERROR; 123 } 124 125 if (data != NULL) { 126 free(data); 127 } 128 129 return ret; 130 } 131 132 #endif 133 134 135 #if (NXT_HAVE_LINUX_UMOUNT2) 136 137 void 138 nxt_fs_unmount(const u_char *path) 139 { 140 if (nxt_slow_path(umount2((const char *) path, MNT_DETACH) < 0)) { 141 nxt_thread_log_error(NXT_LOG_WARN, "umount2(%s, MNT_DETACH) %E", 142 path, nxt_errno); 143 } 144 } 145 146 #elif (NXT_HAVE_UNMOUNT) 147 148 void 149 nxt_fs_unmount(const u_char *path) 150 { 151 if (nxt_slow_path(unmount((const char *) path, MNT_FORCE) < 0)) { 152 nxt_thread_log_error(NXT_LOG_WARN, "unmount(%s) %E", path, nxt_errno); 153 } 154 } 155 156 #endif 157 158 159 nxt_int_t 160 nxt_fs_mkdir_all(const u_char *dir, mode_t mode) 161 { 162 char *start, *end, *dst; 163 size_t dirlen; 164 char path[PATH_MAX]; 165 166 dirlen = nxt_strlen(dir); 167 168 nxt_assert(dirlen < PATH_MAX && dirlen > 1 && dir[0] == '/'); 169 170 dst = path; 171 start = end = (char *) dir; 172 173 while (*start != '\0') { 174 if (*start == '/') { 175 *dst++ = *start++; 176 } 177 178 end = strchr(start, '/'); 179 if (end == NULL) { 180 end = ((char *)dir + dirlen); 181 } 182 183 dst = nxt_cpymem(dst, start, end - start); 184 *dst = '\0'; 185 186 if (nxt_slow_path(nxt_fs_mkdir((u_char *) path, mode) != NXT_OK 187 && nxt_errno != EEXIST)) 188 { 189 return NXT_ERROR; 190 } 191 192 start = end; 193 } 194 195 return NXT_OK; 196 } 197 198 199 static nxt_int_t 200 nxt_fs_mkdir(const u_char *dir, mode_t mode) 201 { 202 if (nxt_fast_path(mkdir((const char *) dir, mode) == 0)) { 203 return NXT_OK; 204 } 205 206 return NXT_ERROR; 207 } 208