xref: /unit/src/nxt_fs.c (revision 1489:4a3ec07f4b19)
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     const char    *fstype;
44     uint8_t       is_bind, is_proc;
45     struct iovec  iov[8];
46     char          errmsg[256];
47 
48     is_bind = nxt_strncmp(mnt->fstype, "bind", 4) == 0;
49     is_proc = nxt_strncmp(mnt->fstype, "proc", 4) == 0;
50 
51     if (nxt_slow_path(!is_bind && !is_proc)) {
52         nxt_alert(task, "mount type \"%s\" not implemented.", mnt->fstype);
53         return NXT_ERROR;
54     }
55 
56     if (is_bind) {
57         fstype = "nullfs";
58 
59     } else {
60         fstype = "procfs";
61     }
62 
63     iov[0].iov_base = (void *) "fstype";
64     iov[0].iov_len = 7;
65     iov[1].iov_base = (void *) fstype;
66     iov[1].iov_len = strlen(fstype) + 1;
67     iov[2].iov_base = (void *) "fspath";
68     iov[2].iov_len = 7;
69     iov[3].iov_base = (void *) mnt->dst;
70     iov[3].iov_len = nxt_strlen(mnt->dst) + 1;
71     iov[4].iov_base = (void *) "target";
72     iov[4].iov_len = 7;
73     iov[5].iov_base = (void *) mnt->src;
74     iov[5].iov_len = nxt_strlen(mnt->src) + 1;
75     iov[6].iov_base = (void *) "errmsg";
76     iov[6].iov_len = 7;
77     iov[7].iov_base = (void *) errmsg;
78     iov[7].iov_len = sizeof(errmsg);
79 
80     if (nxt_slow_path(nmount(iov, 8, 0) < 0)) {
81         nxt_alert(task, "nmount(%p, 8, 0) %s", errmsg);
82         return NXT_ERROR;
83     }
84 
85     return NXT_OK;
86 }
87 
88 #endif
89 
90 
91 #if (NXT_HAVE_LINUX_UMOUNT2)
92 
93 void
94 nxt_fs_unmount(const u_char *path)
95 {
96     if (nxt_slow_path(umount2((const char *) path, MNT_DETACH) < 0)) {
97         nxt_thread_log_error(NXT_LOG_WARN, "umount2(%s, MNT_DETACH) %E",
98                              path, nxt_errno);
99     }
100 }
101 
102 #elif (NXT_HAVE_UNMOUNT)
103 
104 void
105 nxt_fs_unmount(const u_char *path)
106 {
107     if (nxt_slow_path(unmount((const char *) path, MNT_FORCE) < 0)) {
108         nxt_thread_log_error(NXT_LOG_WARN, "unmount(%s) %E", path, nxt_errno);
109     }
110 }
111 
112 #endif
113 
114 
115 nxt_int_t
116 nxt_fs_mkdir_all(const u_char *dir, mode_t mode)
117 {
118     char    *start, *end, *dst;
119     size_t  dirlen;
120     char    path[PATH_MAX];
121 
122     dirlen = nxt_strlen(dir);
123 
124     nxt_assert(dirlen < PATH_MAX && dirlen > 1 && dir[0] == '/');
125 
126     dst = path;
127     start = end = (char *) dir;
128 
129     while (*start != '\0') {
130         if (*start == '/') {
131             *dst++ = *start++;
132         }
133 
134         end = strchr(start, '/');
135         if (end == NULL) {
136             end = ((char *)dir + dirlen);
137         }
138 
139         dst = nxt_cpymem(dst, start, end - start);
140         *dst = '\0';
141 
142         if (nxt_slow_path(nxt_fs_mkdir((u_char *) path, mode) != NXT_OK
143                           && nxt_errno != EEXIST))
144         {
145             return NXT_ERROR;
146         }
147 
148         start = end;
149     }
150 
151     return NXT_OK;
152 }
153 
154 
155 static nxt_int_t
156 nxt_fs_mkdir(const u_char *dir, mode_t mode)
157 {
158     if (nxt_fast_path(mkdir((const char *) dir, mode) == 0)) {
159         return NXT_OK;
160     }
161 
162     return NXT_ERROR;
163 }
164