/* * Unlinks the files contained in @dir and then removes @dir. * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We * ignore ENOENT errors for anything (they happen, strangely enough - possibly * due to races between multiple dying UML threads).
*/ staticint remove_files_and_dir(char *dir)
{
DIR *directory; struct dirent *ent; int len; char file[256]; int ret;
directory = opendir(dir); if (directory == NULL) { if (errno != ENOENT) return -errno; else return 0;
}
while ((ent = readdir(directory)) != NULL) { if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue;
len = strlen(dir) + strlen("/") + strlen(ent->d_name) + 1; if (len > sizeof(file)) {
ret = -E2BIG; goto out;
}
sprintf(file, "%s/%s", dir, ent->d_name); if (unlink(file) < 0 && errno != ENOENT) {
ret = -errno; goto out;
}
}
if (rmdir(dir) < 0 && errno != ENOENT) {
ret = -errno; goto out;
}
ret = 0;
out:
closedir(directory); return ret;
}
/* * This says that there isn't already a user of the specified directory even if * there are errors during the checking. This is because if these errors * happen, the directory is unusable by the pre-existing UML, so we might as * well take it over. This could happen either by * the existing UML somehow corrupting its umid directory * something other than UML sticking stuff in the directory * this boot racing with a shutdown of the other UML * In any of these cases, the directory isn't useful for anything else. * * Boolean return: 1 if in use, 0 otherwise.
*/ staticinlineint is_umdir_used(char *dir)
{ char pid[sizeof("nnnnnnnnn")], *end, *file; int fd, p, n, err;
size_t filelen = strlen(dir) + sizeof("/pid") + 1;
file = malloc(filelen); if (!file) return -ENOMEM;
/* * Try to remove the directory @dir unless it's in use. * Precondition: @dir exists. * Returns 0 for success, < 0 for failure in removal or if the directory is in * use.
*/ staticint umdir_take_if_dead(char *dir)
{ int ret; if (is_umdir_used(dir)) return -EEXIST;
ret = remove_files_and_dir(dir); if (ret) {
printk(UM_KERN_ERR "is_umdir_used - remove_files_and_dir " "failed with err = %d\n", ret);
} return ret;
}
staticvoid __init create_pid_file(void)
{ char pid[sizeof("nnnnnnnnn")], *file; int fd, n;
n = strlen(uml_dir) + UMID_LEN + sizeof("/pid");
file = malloc(n); if (!file) return;
/* * There's a nice tiny little race between this unlink and * the mkdir below. It'd be nice if there were a mkstemp * for directories.
*/ if (unlink(tmp)) {
err = -errno; goto err;
}
}
staticint __init make_umid_init(void)
{ if (!make_umid()) return 0;
/* * If initializing with the given umid failed, then try again with * a random one.
*/
printk(UM_KERN_ERR "Failed to initialize umid \"%s\", trying with a " "random umid\n", umid);
*umid = '\0';
make_umid();
return 0;
}
__initcall(make_umid_init);
int __init umid_file_name(char *name, char *buf, int len)
{ int n, err;
err = make_umid(); if (err) return err;
n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name); if (n >= len) {
printk(UM_KERN_ERR "umid_file_name : buffer too short\n"); return -E2BIG;
}
return 0;
}
char *get_umid(void)
{ return umid;
}
staticint __init set_uml_dir(char *name, int *add)
{
*add = 0;
if (*name == '\0') {
os_warn("uml_dir can't be an empty string\n"); return 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.