]>
Commit | Line | Data |
---|---|---|
1815bff5 A |
1 | #define mig_external |
2 | ||
c3a08f59 | 3 | #include <sys/mount.h> |
1815bff5 A |
4 | #include <sys/stat.h> |
5 | #include <sys/sysctl.h> | |
1815bff5 A |
6 | #include <stdio.h> |
7 | #include <stdlib.h> | |
8 | #include <string.h> | |
1815bff5 | 9 | #include <unistd.h> |
34d340d7 A |
10 | #include <dirent.h> |
11 | ||
c3a08f59 | 12 | /* |
1a7e3f61 A |
13 | * We don't exit with a non-zero status anywhere here for 2 reasons: |
14 | * - the kernel can continue to create swapfiles in "/private/var/vm/swapfile<index>" | |
15 | * - we want this job to run only once at boot and exit regardless of whether: | |
16 | * -- it could clean up the swap directory | |
17 | * -- it could set the prefix for the swapfile name. | |
c3a08f59 | 18 | */ |
c3a08f59 | 19 | |
34d340d7 A |
20 | static void |
21 | clean_swap_directory(const char *path) | |
22 | { | |
23 | DIR *dir; | |
24 | struct dirent *entry; | |
25 | char buf[1024]; | |
26 | ||
27 | dir = opendir(path); | |
28 | if (dir == NULL) { | |
29 | fprintf(stderr,"dynamic_pager: cannot open swap directory %s\n", path); | |
1a7e3f61 | 30 | exit(0); |
34d340d7 A |
31 | } |
32 | ||
33 | while ((entry = readdir(dir)) != NULL) { | |
34 | if (entry->d_namlen>= 4 && strncmp(entry->d_name, "swap", 4) == 0) { | |
35 | snprintf(buf, sizeof buf, "%s/%s", path, entry->d_name); | |
cf37c299 | 36 | unlink(buf); |
34d340d7 A |
37 | } |
38 | } | |
39 | ||
40 | closedir(dir); | |
41 | } | |
42 | ||
1815bff5 A |
43 | int |
44 | main(int argc, char **argv) | |
45 | { | |
1815bff5 | 46 | int ch; |
8459d725 A |
47 | static char tmp[1024]; |
48 | struct statfs sfs; | |
49 | char *q; | |
1a7e3f61 | 50 | char fileroot[512]; |
1815bff5 A |
51 | |
52 | seteuid(getuid()); | |
887d5eed | 53 | fileroot[0] = '\0'; |
1815bff5 | 54 | |
1a7e3f61 | 55 | while ((ch = getopt(argc, argv, "F:")) != EOF) { |
1815bff5 A |
56 | switch((char)ch) { |
57 | ||
58 | case 'F': | |
59 | strncpy(fileroot, optarg, 500); | |
60 | break; | |
61 | ||
1815bff5 A |
62 | default: |
63 | (void)fprintf(stderr, | |
1a7e3f61 A |
64 | "usage: dynamic_pager [-F filename]\n"); |
65 | exit(0); | |
1815bff5 A |
66 | } |
67 | } | |
c3a08f59 | 68 | |
887d5eed A |
69 | /* |
70 | * set vm.swapfileprefix if a fileroot was passed from the command | |
71 | * line, otherwise get the value from the kernel | |
72 | */ | |
73 | if (fileroot[0] != '\0') { | |
74 | if (sysctlbyname("vm.swapfileprefix", NULL, 0, fileroot, sizeof(fileroot)) == -1) { | |
75 | perror("Failed to set swapfile name prefix"); | |
76 | } | |
77 | } else { | |
78 | size_t fileroot_len = sizeof(fileroot); | |
79 | if (sysctlbyname("vm.swapfileprefix", fileroot, &fileroot_len, NULL, 0) == -1) { | |
80 | perror("Failed to get swapfile name prefix"); | |
81 | /* | |
82 | * can't continue without a fileroot | |
83 | */ | |
84 | return (0); | |
85 | } | |
86 | } | |
87 | ||
8459d725 A |
88 | /* |
89 | * get rid of the filename at the end of the swap file specification | |
90 | * we only want the portion of the pathname that should already exist | |
91 | */ | |
92 | strcpy(tmp, fileroot); | |
93 | if ((q = strrchr(tmp, '/'))) | |
94 | *q = 0; | |
95 | ||
96 | /* | |
97 | * Remove all files in the swap directory. | |
98 | */ | |
99 | clean_swap_directory(tmp); | |
100 | ||
8459d725 | 101 | if (statfs(tmp, &sfs) == -1) { |
c3a08f59 | 102 | /* |
cf37c299 A |
103 | * Setup the swap directory. |
104 | */ | |
c3a08f59 | 105 | |
cf37c299 A |
106 | if (mkdir(tmp, 0755) == -1) { |
107 | (void)fprintf(stderr, "dynamic_pager: cannot create swap directory %s\n", tmp); | |
8459d725 | 108 | } |
c3a08f59 | 109 | } |
c3a08f59 | 110 | |
1a7e3f61 | 111 | chown(tmp, 0, 0); |
c3a08f59 | 112 | |
1815bff5 A |
113 | return (0); |
114 | } |