aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2006-01-06 03:18:59 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:47 -0500
commit2264c475e4bf7427e59921953c89a5693ecb506f (patch)
tree4ebf1fa766ee7487eeaf583f1ffe2b63e6e0af2c
parente4dcee8099802c71437a15b940f66106d9f88b2f (diff)
[PATCH] uml: separate libc-dependent umid code
I reworked Gennady's umid OS abstraction patch because the code shouldn't be moved entirely to os. As it turns out, I moved most of it anyway. This patch is the minimal one needed to move the code and have it work. It turns out that the concept of the umid is OS-independent, but almost everything else about the implementation is OS-dependent. This is code movement without cleanup - a follow-on patch tidies everything up without shuffling code around. Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/um/include/kern.h13
-rw-r--r--arch/um/include/os.h17
-rw-r--r--arch/um/kernel/Makefile6
-rw-r--r--arch/um/kernel/process_kern.c4
-rw-r--r--arch/um/kernel/umid.c327
-rw-r--r--arch/um/os-Linux/Makefile4
-rw-r--r--arch/um/os-Linux/umid.c292
7 files changed, 324 insertions, 339 deletions
diff --git a/arch/um/include/kern.h b/arch/um/include/kern.h
index 1e3170768b5c..7d223beccbc0 100644
--- a/arch/um/include/kern.h
+++ b/arch/um/include/kern.h
@@ -17,7 +17,7 @@ extern int errno;
17 17
18extern int clone(int (*proc)(void *), void *sp, int flags, void *data); 18extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
19extern int sleep(int); 19extern int sleep(int);
20extern int printf(char *fmt, ...); 20extern int printf(const char *fmt, ...);
21extern char *strerror(int errnum); 21extern char *strerror(int errnum);
22extern char *ptsname(int __fd); 22extern char *ptsname(int __fd);
23extern int munmap(void *, int); 23extern int munmap(void *, int);
@@ -35,15 +35,6 @@ extern int read(unsigned int, char *, int);
35extern int pipe(int *); 35extern int pipe(int *);
36extern int sched_yield(void); 36extern int sched_yield(void);
37extern int ptrace(int op, int pid, long addr, long data); 37extern int ptrace(int op, int pid, long addr, long data);
38
38#endif 39#endif
39 40
40/*
41 * Overrides for Emacs so that we follow Linus's tabbing style.
42 * Emacs will notice this stuff at the end of the file and automatically
43 * adjust the settings for this buffer only. This must remain at the end
44 * of the file.
45 * ---------------------------------------------------------------------------
46 * Local variables:
47 * c-file-style: "linux"
48 * End:
49 */
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 2cccfa5b8ab5..258444e5b9bc 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -213,15 +213,10 @@ extern int run_helper_thread(int (*proc)(void *), void *arg,
213 int stack_order); 213 int stack_order);
214extern int helper_wait(int pid); 214extern int helper_wait(int pid);
215 215
216#endif 216/* umid.c */
217 217
218/* 218extern int umid_file_name(char *name, char *buf, int len);
219 * Overrides for Emacs so that we follow Linus's tabbing style. 219extern int set_umid(char *name, int (*printer)(const char *fmt, ...));
220 * Emacs will notice this stuff at the end of the file and automatically 220extern char *get_umid(int only_if_set);
221 * adjust the settings for this buffer only. This must remain at the end 221
222 * of the file. 222#endif
223 * ---------------------------------------------------------------------------
224 * Local variables:
225 * c-file-style: "linux"
226 * End:
227 */
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 3de9d21e36bf..6f7700593a6f 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -10,8 +10,8 @@ obj-y = config.o exec_kern.o exitcode.o \
10 init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \ 10 init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \
11 process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \ 11 process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
12 signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \ 12 signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \
13 time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o \ 13 time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o umid.o \
14 umid.o user_util.o 14 user_util.o
15 15
16obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 16obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
17obj-$(CONFIG_GPROF) += gprof_syms.o 17obj-$(CONFIG_GPROF) += gprof_syms.o
@@ -24,7 +24,7 @@ obj-$(CONFIG_MODE_SKAS) += skas/
24 24
25user-objs-$(CONFIG_TTY_LOG) += tty_log.o 25user-objs-$(CONFIG_TTY_LOG) += tty_log.o
26 26
27USER_OBJS := $(user-objs-y) config.o time.o tty_log.o umid.o user_util.o 27USER_OBJS := $(user-objs-y) config.o time.o tty_log.o user_util.o
28 28
29include arch/um/scripts/Makefile.rules 29include arch/um/scripts/Makefile.rules
30 30
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 34b54a3e2132..651abf255bc5 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -324,10 +324,6 @@ int user_context(unsigned long sp)
324 return(stack != (unsigned long) current_thread); 324 return(stack != (unsigned long) current_thread);
325} 325}
326 326
327extern void remove_umid_dir(void);
328
329__uml_exitcall(remove_umid_dir);
330
331extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; 327extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
332 328
333void do_uml_exitcalls(void) 329void do_uml_exitcalls(void)
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
index 0b21d59ba0cd..772c7cfbd8ec 100644
--- a/arch/um/kernel/umid.c
+++ b/arch/um/kernel/umid.c
@@ -3,61 +3,34 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h> 6#include "linux/stddef.h"
7#include <unistd.h> 7#include "linux/kernel.h"
8#include <errno.h> 8#include "asm/errno.h"
9#include <string.h>
10#include <stdlib.h>
11#include <dirent.h>
12#include <signal.h>
13#include <sys/stat.h>
14#include <sys/param.h>
15#include "user.h"
16#include "umid.h"
17#include "init.h" 9#include "init.h"
18#include "os.h" 10#include "os.h"
19#include "user_util.h" 11#include "kern.h"
20#include "choose-mode.h"
21 12
22#define UMID_LEN 64 13/* Changed by set_umid_arg and umid_file_name */
23#define UML_DIR "~/.uml/" 14int umid_is_random = 0;
24
25/* Changed by set_umid and make_umid, which are run early in boot */
26static char umid[UMID_LEN] = { 0 };
27
28/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
29static char *uml_dir = UML_DIR;
30
31/* Changed by set_umid */
32static int umid_is_random = 1;
33static int umid_inited = 0; 15static int umid_inited = 0;
34/* Have we created the files? Should we remove them? */
35static int umid_owned = 0;
36 16
37static int make_umid(int (*printer)(const char *fmt, ...)); 17static int __init set_umid_arg(char *name, int *add)
38
39static int __init set_umid(char *name, int is_random,
40 int (*printer)(const char *fmt, ...))
41{ 18{
42 if(umid_inited){ 19 int err;
43 (*printer)("Unique machine name can't be set twice\n");
44 return(-1);
45 }
46 20
47 if(strlen(name) > UMID_LEN - 1) 21 if(umid_inited)
48 (*printer)("Unique machine name is being truncated to %d " 22 return 0;
49 "characters\n", UMID_LEN);
50 strlcpy(umid, name, sizeof(umid));
51 23
52 umid_is_random = is_random;
53 umid_inited = 1;
54 return 0;
55}
56
57static int __init set_umid_arg(char *name, int *add)
58{
59 *add = 0; 24 *add = 0;
60 return(set_umid(name, 0, printf)); 25 err = set_umid(name, printf);
26 if(err == -EEXIST){
27 printf("umid '%s' already in use\n", name);
28 umid_is_random = 1;
29 }
30 else if(!err)
31 umid_inited = 1;
32
33 return 0;
61} 34}
62 35
63__uml_setup("umid=", set_umid_arg, 36__uml_setup("umid=", set_umid_arg,
@@ -66,265 +39,3 @@ __uml_setup("umid=", set_umid_arg,
66" is used for naming the pid file and management console socket.\n\n" 39" is used for naming the pid file and management console socket.\n\n"
67); 40);
68 41
69int __init umid_file_name(char *name, char *buf, int len)
70{
71 int n;
72
73 if(!umid_inited && make_umid(printk)) return(-1);
74
75 n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
76 if(n > len){
77 printk("umid_file_name : buffer too short\n");
78 return(-1);
79 }
80
81 sprintf(buf, "%s%s/%s", uml_dir, umid, name);
82 return(0);
83}
84
85extern int tracing_pid;
86
87static void __init create_pid_file(void)
88{
89 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
90 char pid[sizeof("nnnnn\0")];
91 int fd, n;
92
93 if(umid_file_name("pid", file, sizeof(file)))
94 return;
95
96 fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
97 0644);
98 if(fd < 0){
99 printf("Open of machine pid file \"%s\" failed: %s\n",
100 file, strerror(-fd));
101 return;
102 }
103
104 sprintf(pid, "%d\n", os_getpid());
105 n = os_write_file(fd, pid, strlen(pid));
106 if(n != strlen(pid))
107 printf("Write of pid file failed - err = %d\n", -n);
108 os_close_file(fd);
109}
110
111static int actually_do_remove(char *dir)
112{
113 DIR *directory;
114 struct dirent *ent;
115 int len;
116 char file[256];
117
118 directory = opendir(dir);
119 if(directory == NULL){
120 printk("actually_do_remove : couldn't open directory '%s', "
121 "errno = %d\n", dir, errno);
122 return(1);
123 }
124 while((ent = readdir(directory)) != NULL){
125 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
126 continue;
127 len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
128 if(len > sizeof(file)){
129 printk("Not deleting '%s' from '%s' - name too long\n",
130 ent->d_name, dir);
131 continue;
132 }
133 sprintf(file, "%s/%s", dir, ent->d_name);
134 if(unlink(file) < 0){
135 printk("actually_do_remove : couldn't remove '%s' "
136 "from '%s', errno = %d\n", ent->d_name, dir,
137 errno);
138 return(1);
139 }
140 }
141 if(rmdir(dir) < 0){
142 printk("actually_do_remove : couldn't rmdir '%s', "
143 "errno = %d\n", dir, errno);
144 return(1);
145 }
146 return(0);
147}
148
149void remove_umid_dir(void)
150{
151 char dir[strlen(uml_dir) + UMID_LEN + 1];
152 if (!umid_owned)
153 return;
154
155 sprintf(dir, "%s%s", uml_dir, umid);
156 actually_do_remove(dir);
157}
158
159char *get_umid(int only_if_set)
160{
161 if(only_if_set && umid_is_random)
162 return NULL;
163 return umid;
164}
165
166static int not_dead_yet(char *dir)
167{
168 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
169 char pid[sizeof("nnnnn\0")], *end;
170 int dead, fd, p, n;
171
172 sprintf(file, "%s/pid", dir);
173 dead = 0;
174 fd = os_open_file(file, of_read(OPENFLAGS()), 0);
175 if(fd < 0){
176 if(fd != -ENOENT){
177 printk("not_dead_yet : couldn't open pid file '%s', "
178 "err = %d\n", file, -fd);
179 return(1);
180 }
181 dead = 1;
182 }
183 if(fd > 0){
184 n = os_read_file(fd, pid, sizeof(pid));
185 if(n < 0){
186 printk("not_dead_yet : couldn't read pid file '%s', "
187 "err = %d\n", file, -n);
188 return(1);
189 }
190 p = strtoul(pid, &end, 0);
191 if(end == pid){
192 printk("not_dead_yet : couldn't parse pid file '%s', "
193 "errno = %d\n", file, errno);
194 dead = 1;
195 }
196 if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
197 (p == CHOOSE_MODE(tracing_pid, os_getpid())))
198 dead = 1;
199 }
200 if(!dead)
201 return(1);
202 return(actually_do_remove(dir));
203}
204
205static int __init set_uml_dir(char *name, int *add)
206{
207 if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
208 uml_dir = malloc(strlen(name) + 2);
209 if(uml_dir == NULL){
210 printf("Failed to malloc uml_dir - error = %d\n",
211 errno);
212 uml_dir = name;
213 /* Return 0 here because do_initcalls doesn't look at
214 * the return value.
215 */
216 return(0);
217 }
218 sprintf(uml_dir, "%s/", name);
219 }
220 else uml_dir = name;
221 return(0);
222}
223
224static int __init make_uml_dir(void)
225{
226 char dir[MAXPATHLEN + 1] = { '\0' };
227 int len;
228
229 if(*uml_dir == '~'){
230 char *home = getenv("HOME");
231
232 if(home == NULL){
233 printf("make_uml_dir : no value in environment for "
234 "$HOME\n");
235 exit(1);
236 }
237 strlcpy(dir, home, sizeof(dir));
238 uml_dir++;
239 }
240 strlcat(dir, uml_dir, sizeof(dir));
241 len = strlen(dir);
242 if (len > 0 && dir[len - 1] != '/')
243 strlcat(dir, "/", sizeof(dir));
244
245 uml_dir = malloc(strlen(dir) + 1);
246 if (uml_dir == NULL) {
247 printf("make_uml_dir : malloc failed, errno = %d\n", errno);
248 exit(1);
249 }
250 strcpy(uml_dir, dir);
251
252 if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
253 printf("Failed to mkdir %s: %s\n", uml_dir, strerror(errno));
254 return(-1);
255 }
256 return 0;
257}
258
259static int __init make_umid(int (*printer)(const char *fmt, ...))
260{
261 int fd, err;
262 char tmp[strlen(uml_dir) + UMID_LEN + 1];
263
264 strlcpy(tmp, uml_dir, sizeof(tmp));
265
266 if(!umid_inited){
267 strcat(tmp, "XXXXXX");
268 fd = mkstemp(tmp);
269 if(fd < 0){
270 (*printer)("make_umid - mkstemp(%s) failed: %s\n",
271 tmp,strerror(errno));
272 return(1);
273 }
274
275 os_close_file(fd);
276 /* There's a nice tiny little race between this unlink and
277 * the mkdir below. It'd be nice if there were a mkstemp
278 * for directories.
279 */
280 unlink(tmp);
281 set_umid(&tmp[strlen(uml_dir)], 1, printer);
282 }
283
284 sprintf(tmp, "%s%s", uml_dir, umid);
285
286 err = mkdir(tmp, 0777);
287 if(err < 0){
288 if(errno == EEXIST){
289 if(not_dead_yet(tmp)){
290 (*printer)("umid '%s' is in use\n", umid);
291 umid_owned = 0;
292 return(-1);
293 }
294 err = mkdir(tmp, 0777);
295 }
296 }
297 if(err < 0){
298 (*printer)("Failed to create %s - errno = %d\n", umid, errno);
299 return(-1);
300 }
301
302 umid_owned = 1;
303 return 0;
304}
305
306__uml_setup("uml_dir=", set_uml_dir,
307"uml_dir=<directory>\n"
308" The location to place the pid and umid files.\n\n"
309);
310
311static int __init make_umid_setup(void)
312{
313 /* one function with the ordering we need ... */
314 make_uml_dir();
315 make_umid(printf);
316 create_pid_file();
317 return 0;
318}
319__uml_postsetup(make_umid_setup);
320
321/*
322 * Overrides for Emacs so that we follow Linus's tabbing style.
323 * Emacs will notice this stuff at the end of the file and automatically
324 * adjust the settings for this buffer only. This must remain at the end
325 * of the file.
326 * ---------------------------------------------------------------------------
327 * Local variables:
328 * c-file-style: "linux"
329 * End:
330 */
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index b83ac8e21c35..11e30b13e318 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -4,11 +4,11 @@
4# 4#
5 5
6obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 6obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
7 start_up.o time.o tt.o tty.o uaccess.o user_syms.o drivers/ \ 7 start_up.o time.o tt.o tty.o uaccess.o umid.o user_syms.o drivers/ \
8 sys-$(SUBARCH)/ 8 sys-$(SUBARCH)/
9 9
10USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 10USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
11 start_up.o time.o tt.o tty.o uaccess.o 11 start_up.o time.o tt.o tty.o uaccess.o umid.o
12 12
13elf_aux.o: $(ARCH_DIR)/kernel-offsets.h 13elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
14CFLAGS_elf_aux.o += -I$(objtree)/arch/um 14CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
new file mode 100644
index 000000000000..77d69a348cf4
--- /dev/null
+++ b/arch/um/os-Linux/umid.c
@@ -0,0 +1,292 @@
1#include <stdio.h>
2#include <unistd.h>
3#include <stdlib.h>
4#include <string.h>
5#include <errno.h>
6#include <signal.h>
7#include <dirent.h>
8#include <sys/stat.h>
9#include <sys/param.h>
10#include "init.h"
11#include "os.h"
12#include "user.h"
13#include "mode.h"
14
15#define UML_DIR "~/.uml/"
16
17#define UMID_LEN 64
18
19/* Changed by set_umid, which is run early in boot */
20char umid[UMID_LEN] = { 0 };
21
22/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
23static char *uml_dir = UML_DIR;
24
25static int __init make_uml_dir(void)
26{
27 char dir[512] = { '\0' };
28 int len;
29
30 if(*uml_dir == '~'){
31 char *home = getenv("HOME");
32
33 if(home == NULL){
34 printf("make_uml_dir : no value in environment for "
35 "$HOME\n");
36 exit(1);
37 }
38 strlcpy(dir, home, sizeof(dir));
39 uml_dir++;
40 }
41 strlcat(dir, uml_dir, sizeof(dir));
42 len = strlen(dir);
43 if (len > 0 && dir[len - 1] != '/')
44 strlcat(dir, "/", sizeof(dir));
45
46 uml_dir = malloc(strlen(dir) + 1);
47 if (uml_dir == NULL) {
48 printf("make_uml_dir : malloc failed, errno = %d\n", errno);
49 exit(1);
50 }
51 strcpy(uml_dir, dir);
52
53 if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
54 printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno));
55 return(-1);
56 }
57 return 0;
58}
59
60static int actually_do_remove(char *dir)
61{
62 DIR *directory;
63 struct dirent *ent;
64 int len;
65 char file[256];
66
67 directory = opendir(dir);
68 if(directory == NULL){
69 printk("actually_do_remove : couldn't open directory '%s', "
70 "errno = %d\n", dir, errno);
71 return(1);
72 }
73 while((ent = readdir(directory)) != NULL){
74 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
75 continue;
76 len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
77 if(len > sizeof(file)){
78 printk("Not deleting '%s' from '%s' - name too long\n",
79 ent->d_name, dir);
80 continue;
81 }
82 sprintf(file, "%s/%s", dir, ent->d_name);
83 if(unlink(file) < 0){
84 printk("actually_do_remove : couldn't remove '%s' "
85 "from '%s', errno = %d\n", ent->d_name, dir,
86 errno);
87 return(1);
88 }
89 }
90 if(rmdir(dir) < 0){
91 printk("actually_do_remove : couldn't rmdir '%s', "
92 "errno = %d\n", dir, errno);
93 return(1);
94 }
95 return(0);
96}
97
98extern int tracing_pid;
99
100static int not_dead_yet(char *dir)
101{
102 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
103 char pid[sizeof("nnnnn\0")], *end;
104 int dead, fd, p, n;
105
106 sprintf(file, "%s/pid", dir);
107 dead = 0;
108 fd = os_open_file(file, of_read(OPENFLAGS()), 0);
109 if(fd < 0){
110 if(fd != -ENOENT){
111 printk("not_dead_yet : couldn't open pid file '%s', "
112 "err = %d\n", file, -fd);
113 return(1);
114 }
115 dead = 1;
116 }
117 if(fd > 0){
118 n = os_read_file(fd, pid, sizeof(pid));
119 if(n < 0){
120 printk("not_dead_yet : couldn't read pid file '%s', "
121 "err = %d\n", file, -n);
122 return(1);
123 }
124 p = strtoul(pid, &end, 0);
125 if(end == pid){
126 printk("not_dead_yet : couldn't parse pid file '%s', "
127 "errno = %d\n", file, errno);
128 dead = 1;
129 }
130 if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
131 (p == CHOOSE_MODE(tracing_pid, os_getpid())))
132 dead = 1;
133 }
134 if(!dead)
135 return(1);
136 return(actually_do_remove(dir));
137}
138
139static void __init create_pid_file(void)
140{
141 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
142 char pid[sizeof("nnnnn\0")];
143 int fd, n;
144
145 if(umid_file_name("pid", file, sizeof(file)))
146 return;
147
148 fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
149 0644);
150 if(fd < 0){
151 printf("Open of machine pid file \"%s\" failed: %s\n",
152 file, strerror(-fd));
153 return;
154 }
155
156 sprintf(pid, "%d\n", os_getpid());
157 n = os_write_file(fd, pid, strlen(pid));
158 if(n != strlen(pid))
159 printf("Write of pid file failed - err = %d\n", -n);
160 os_close_file(fd);
161}
162
163int __init set_umid(char *name, int (*printer)(const char *fmt, ...))
164{
165 if(strlen(name) > UMID_LEN - 1)
166 (*printer)("Unique machine name is being truncated to %d "
167 "characters\n", UMID_LEN);
168 strlcpy(umid, name, sizeof(umid));
169
170 return 0;
171}
172
173static int umid_setup = 0;
174
175int __init make_umid(int (*printer)(const char *fmt, ...))
176{
177 int fd, err;
178 char tmp[256];
179
180 make_uml_dir();
181
182 if(*umid == '\0'){
183 strlcpy(tmp, uml_dir, sizeof(tmp));
184 strcat(tmp, "XXXXXX");
185 fd = mkstemp(tmp);
186 if(fd < 0){
187 (*printer)("make_umid - mkstemp(%s) failed: %s\n",
188 tmp,strerror(errno));
189 return(1);
190 }
191
192 os_close_file(fd);
193 /* There's a nice tiny little race between this unlink and
194 * the mkdir below. It'd be nice if there were a mkstemp
195 * for directories.
196 */
197 unlink(tmp);
198 set_umid(&tmp[strlen(uml_dir)], printer);
199 }
200
201 sprintf(tmp, "%s%s", uml_dir, umid);
202 err = mkdir(tmp, 0777);
203 if(err < 0){
204 if(errno == EEXIST){
205 if(not_dead_yet(tmp))
206 return -EEXIST;
207 err = mkdir(tmp, 0777);
208 }
209 }
210 if(err < 0){
211 (*printer)("Failed to create %s - errno = %d\n", umid, errno);
212 return(-1);
213 }
214
215 umid_setup = 1;
216
217 create_pid_file();
218
219 return 0;
220}
221
222static int __init make_umid_init(void)
223{
224 make_umid(printk);
225
226 return(0);
227}
228
229__initcall(make_umid_init);
230
231int __init umid_file_name(char *name, char *buf, int len)
232{
233 int n, err;
234
235 if(!umid_setup){
236 err = make_umid(printk);
237 if(err)
238 return err;
239 }
240
241 n = strlen(uml_dir) + strlen(umid) + strlen("/") + strlen(name) + 1;
242 if(n > len){
243 printk("umid_file_name : buffer too short\n");
244 return(-1);
245 }
246
247 sprintf(buf, "%s%s/%s", uml_dir, umid, name);
248 return(0);
249}
250
251extern int umid_is_random;
252
253char *get_umid(int only_if_set)
254{
255 if(only_if_set && umid_is_random)
256 return NULL;
257 return umid;
258}
259
260static int __init set_uml_dir(char *name, int *add)
261{
262 if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
263 uml_dir = malloc(strlen(name) + 2);
264 if(uml_dir == NULL){
265 printf("Failed to malloc uml_dir - error = %d\n",
266 errno);
267 uml_dir = name;
268 /* Return 0 here because do_initcalls doesn't look at
269 * the return value.
270 */
271 return(0);
272 }
273 sprintf(uml_dir, "%s/", name);
274 }
275 else uml_dir = name;
276 return(0);
277}
278
279__uml_setup("uml_dir=", set_uml_dir,
280"uml_dir=<directory>\n"
281" The location to place the pid and umid files.\n\n"
282);
283
284static void remove_umid_dir(void)
285{
286 char dir[strlen(uml_dir) + UMID_LEN + 1];
287
288 sprintf(dir, "%s%s", uml_dir, umid);
289 actually_do_remove(dir);
290}
291
292__uml_exitcall(remove_umid_dir);