#include <libubox/avl-cmp.h>
#include <libubox/blobmsg.h>
#include <libubox/list.h>
+#include <libubox/utils.h>
#include "elf.h"
#include "fs.h"
struct avl_tree mounts;
-int mkdir_p(char *dir, mode_t mask)
-{
- char *l = strrchr(dir, '/');
- int ret;
-
- if (!l)
- return 0;
-
- *l = '\0';
-
- if (mkdir_p(dir, mask))
- return -1;
-
- *l = '/';
-
- ret = mkdir(dir, mask);
- if (ret && errno == EEXIST)
- return 0;
-
- if (ret)
- ERROR("mkdir(%s, %d) failed: %m\n", dir, mask);
-
- return ret;
-}
-
static int do_mount(const char *root, const char *orig_source, const char *target, const char *filesystemtype,
unsigned long orig_mountflags, unsigned long propflags, const char *optstr, int error, bool inner)
{
return error;
} else {
/* mount-bind 0-sized file having mode 000 */
- if (mount(UJAIL_NOAFILE, new, NULL, MS_BIND, NULL))
+ if (mount(UJAIL_NOAFILE, new, "bind", MS_BIND, NULL))
return error;
- if (mount(UJAIL_NOAFILE, new, NULL, MS_REMOUNT | MS_BIND | MS_RDONLY | MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_NOATIME, NULL))
+ if (mount(UJAIL_NOAFILE, new, "bind", MS_REMOUNT | MS_BIND | MS_RDONLY | MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_NOATIME, NULL))
return error;
}
}
if (is_bind) {
- if (mount(source?:new, new, filesystemtype, MS_BIND | (mountflags & MS_REC), optstr)) {
+ if (mount(source?:new, new, filesystemtype?:"bind", MS_BIND | (mountflags & MS_REC), optstr)) {
if (error)
ERROR("failed to mount -B %s %s: %m\n", source, new);
mountflags |= MS_REMOUNT;
}
- if (mount(source?:(is_bind?new:NULL), new, filesystemtype, mountflags, optstr)) {
+ const char *hack_fstype = ((!filesystemtype || strcmp(filesystemtype, "cgroup"))?filesystemtype:"cgroup2");
+ if (mount(source?:(is_bind?new:NULL), new, hack_fstype?:"none", mountflags, optstr)) {
if (error)
ERROR("failed to mount %s %s: %m\n", source, new);
DEBUG("mount %s%s %s (%s)\n", (mountflags & MS_BIND)?"-B ":"", source, new,
(mountflags & MS_RDONLY)?"ro":"rw");
- if (propflags && mount(NULL, new, NULL, propflags, NULL)) {
+ if (propflags && mount("none", new, "none", propflags, NULL)) {
if (error)
ERROR("failed to mount --make-... %s \n", new);
struct mount *m;
m = calloc(1, sizeof(struct mount));
- assert(m != NULL);
+ if (!m)
+ return ENOMEM;
+
m->avl.key = m->target = strdup(target);
if (source) {
if (source != (void*)(-1))
char *tmp;
struct list_head fsopts = LIST_HEAD_INIT(fsopts);
size_t len = 0;
- struct mount_opt *opt;
+ struct mount_opt *opt, *tmpopt;
blobmsg_for_each_attr(cur, msg, rem) {
tmp = blobmsg_get_string(cur);
strcat(*mount_data, opt->optstr);
++len;
- };
+ }
- list_del(&fsopts);
+ list_for_each_entry_safe(opt, tmpopt, &fsopts, list) {
+ list_del(&opt->list);
+ free(opt);
+ }
}
DEBUG("mount flags(%08lx) propagation(%08lx) fsopts(\"%s\")\n", mf, pf, *mount_data?:"");
return 0;
}
+void mount_free(void) {
+ struct mount *m, *tmp;
+
+ avl_remove_all_elements(&mounts, m, avl, tmp) {
+ if (m->source != (void*)(-1))
+ free((void*)m->source);
+ free((void*)m->target);
+ free((void*)m->filesystemtype);
+ free((void*)m->optstr);
+ free(m);
+ }
+}
+
void mount_list_init(void) {
avl_init(&mounts, avl_strcmp, false, NULL);
}