X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fum%2Fos-Linux%2Fumid.c;fp=arch%2Fum%2Fos-Linux%2Fumid.c;h=ecf107ae5ac87704afc39021c9c178b6fc641547;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=48092b95c8ab997b4914a072afcd17f0e1aa7eda;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index 48092b95c..ecf107ae5 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -67,53 +67,32 @@ err: return err; } -/* - * 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). - */ -static int remove_files_and_dir(char *dir) +static int actually_do_remove(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; - } + if(directory == NULL) + return -errno; - while ((ent = readdir(directory)) != NULL) { - if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) + while((ent = readdir(directory)) != NULL){ + if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue; len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1; - if (len > sizeof(file)) { - ret = -E2BIG; - goto out; - } + if(len > sizeof(file)) + return -E2BIG; 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; + if(unlink(file) < 0) + return -errno; } + if(rmdir(dir) < 0) + return -errno; - ret = 0; -out: - closedir(directory); - return ret; + return 0; } /* This says that there isn't already a user of the specified directory even if @@ -124,10 +103,9 @@ out: * 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. */ -static inline int is_umdir_used(char *dir) + +static int not_dead_yet(char *dir) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; char pid[sizeof("nnnnn\0")], *end; @@ -135,17 +113,16 @@ static inline int is_umdir_used(char *dir) n = snprintf(file, sizeof(file), "%s/pid", dir); if(n >= sizeof(file)){ - printk("is_umdir_used - pid filename too long\n"); + printk("not_dead_yet - pid filename too long\n"); err = -E2BIG; goto out; } dead = 0; fd = open(file, O_RDONLY); - if(fd < 0) { - fd = -errno; + if(fd < 0){ if(fd != -ENOENT){ - printk("is_umdir_used : couldn't open pid file '%s', " + printk("not_dead_yet : couldn't open pid file '%s', " "err = %d\n", file, -fd); } goto out; @@ -153,54 +130,35 @@ static inline int is_umdir_used(char *dir) err = 0; n = read(fd, pid, sizeof(pid)); - if(n < 0){ - printk("is_umdir_used : couldn't read pid file '%s', " - "err = %d\n", file, errno); - goto out_close; - } else if(n == 0){ - printk("is_umdir_used : couldn't read pid file '%s', " - "0-byte read\n", file); + if(n <= 0){ + printk("not_dead_yet : couldn't read pid file '%s', " + "err = %d\n", file, -n); goto out_close; } p = strtoul(pid, &end, 0); if(end == pid){ - printk("is_umdir_used : couldn't parse pid file '%s', " + printk("not_dead_yet : couldn't parse pid file '%s', " "errno = %d\n", file, errno); goto out_close; } - if((kill(p, 0) == 0) || (errno != ESRCH)){ - printk("umid \"%s\" is already in use by pid %d\n", umid, p); + if((kill(p, 0) == 0) || (errno != ESRCH)) return 1; - } -out_close: + err = actually_do_remove(dir); + if(err) + printk("not_dead_yet - actually_do_remove failed with " + "err = %d\n", err); + + return err; + + out_close: close(fd); -out: + out: return 0; } -/* - * 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. - */ -static int umdir_take_if_dead(char *dir) -{ - int ret; - if (is_umdir_used(dir)) - return -EEXIST; - - ret = remove_files_and_dir(dir); - if (ret) { - printk("is_umdir_used - remove_files_and_dir failed with " - "err = %d\n", ret); - } - return ret; -} - static void __init create_pid_file(void) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; @@ -213,14 +171,14 @@ static void __init create_pid_file(void) fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644); if(fd < 0){ printk("Open of machine pid file \"%s\" failed: %s\n", - file, strerror(errno)); + file, strerror(-fd)); return; } snprintf(pid, sizeof(pid), "%d\n", getpid()); n = write(fd, pid, strlen(pid)); if(n != strlen(pid)) - printk("Write of pid file failed - err = %d\n", errno); + printk("Write of pid file failed - err = %d\n", -n); close(fd); } @@ -276,40 +234,33 @@ int __init make_umid(void) err = mkdir(tmp, 0777); if(err < 0){ err = -errno; - if(err != -EEXIST) + if(errno != EEXIST) goto err; - if (umdir_take_if_dead(tmp) < 0) + if(not_dead_yet(tmp) < 0) goto err; err = mkdir(tmp, 0777); } - if(err){ - err = -errno; - printk("Failed to create '%s' - err = %d\n", umid, -errno); - goto err; + if(err < 0){ + printk("Failed to create '%s' - err = %d\n", umid, err); + goto err_rmdir; } umid_setup = 1; create_pid_file(); - err = 0; + return 0; + + err_rmdir: + rmdir(tmp); err: return err; } static int __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("Failed to initialize umid \"%s\", trying with a random umid\n", - umid); - *umid = '\0'; make_umid(); return 0; @@ -375,9 +326,9 @@ static void remove_umid_dir(void) char dir[strlen(uml_dir) + UMID_LEN + 1], err; sprintf(dir, "%s%s", uml_dir, umid); - err = remove_files_and_dir(dir); + err = actually_do_remove(dir); if(err) - printf("remove_umid_dir - remove_files_and_dir failed with " + printf("remove_umid_dir - actually_do_remove failed with " "err = %d\n", err); }