18e25f19bSMatthew Dillon /*
23bd7e0a7SMatthew Dillon * Copyright (c) 2019-2022 The DragonFly Project. All rights reserved.
38e25f19bSMatthew Dillon *
48e25f19bSMatthew Dillon * This code is derived from software contributed to The DragonFly Project
58e25f19bSMatthew Dillon * by Matthew Dillon <dillon@backplane.com>
68e25f19bSMatthew Dillon *
78e25f19bSMatthew Dillon * This code uses concepts and configuration based on 'synth', by
88e25f19bSMatthew Dillon * John R. Marino <draco@marino.st>, which was written in ada.
98e25f19bSMatthew Dillon *
108e25f19bSMatthew Dillon * Redistribution and use in source and binary forms, with or without
118e25f19bSMatthew Dillon * modification, are permitted provided that the following conditions
128e25f19bSMatthew Dillon * are met:
138e25f19bSMatthew Dillon *
148e25f19bSMatthew Dillon * 1. Redistributions of source code must retain the above copyright
158e25f19bSMatthew Dillon * notice, this list of conditions and the following disclaimer.
168e25f19bSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright
178e25f19bSMatthew Dillon * notice, this list of conditions and the following disclaimer in
188e25f19bSMatthew Dillon * the documentation and/or other materials provided with the
198e25f19bSMatthew Dillon * distribution.
208e25f19bSMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its
218e25f19bSMatthew Dillon * contributors may be used to endorse or promote products derived
228e25f19bSMatthew Dillon * from this software without specific, prior written permission.
238e25f19bSMatthew Dillon *
248e25f19bSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
258e25f19bSMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
268e25f19bSMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
278e25f19bSMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
288e25f19bSMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
298e25f19bSMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
308e25f19bSMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
318e25f19bSMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
328e25f19bSMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
338e25f19bSMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
348e25f19bSMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
358e25f19bSMatthew Dillon * SUCH DAMAGE.
368e25f19bSMatthew Dillon */
378e25f19bSMatthew Dillon #include "dsynth.h"
388e25f19bSMatthew Dillon
398e25f19bSMatthew Dillon static void domount(worker_t *work, int type,
401d6e00cdSMatthew Dillon const char *spath, const char *dpath,
411d6e00cdSMatthew Dillon const char *discretefmt);
428e25f19bSMatthew Dillon static void dounmount(worker_t *work, const char *rpath);
431d6e00cdSMatthew Dillon static void makeDiscreteCopies(const char *spath, const char *discretefmt);
448e25f19bSMatthew Dillon
458e25f19bSMatthew Dillon /*
468e25f19bSMatthew Dillon * Called by the frontend to create a template which will be cpdup'd
478e25f19bSMatthew Dillon * into fresh workers.
488e25f19bSMatthew Dillon *
498e25f19bSMatthew Dillon * Template must have been previously destroyed. Errors are fatal
508e25f19bSMatthew Dillon */
518e25f19bSMatthew Dillon int
DoCreateTemplate(int force)521d6e00cdSMatthew Dillon DoCreateTemplate(int force)
538e25f19bSMatthew Dillon {
541d6e00cdSMatthew Dillon struct stat st;
558ec23ca1SMatthew Dillon char *goodbuf;
568e25f19bSMatthew Dillon char *buf;
57753e4c44SMatthew Dillon const char *reason = "";
588e25f19bSMatthew Dillon int rc;
598ec23ca1SMatthew Dillon int fd;
602074bc97SMatthew Dillon int n;
618e25f19bSMatthew Dillon
628e25f19bSMatthew Dillon rc = 0;
638ec23ca1SMatthew Dillon asprintf(&goodbuf, "%s/.template.good", BuildBase);
641d6e00cdSMatthew Dillon
651d6e00cdSMatthew Dillon /*
661d6e00cdSMatthew Dillon * Conditionally create the template and discrete copies of certain
671d6e00cdSMatthew Dillon * directories if we think we are missing things.
681d6e00cdSMatthew Dillon */
69753e4c44SMatthew Dillon if (force == 1)
70753e4c44SMatthew Dillon reason = " (Asked to force template creation)";
711d6e00cdSMatthew Dillon if (force == 0) {
722074bc97SMatthew Dillon time_t ls_mtime;
732074bc97SMatthew Dillon
741d6e00cdSMatthew Dillon asprintf(&buf, "%s/Template", BuildBase);
75753e4c44SMatthew Dillon if (stat(buf, &st) < 0) {
761d6e00cdSMatthew Dillon force = 1;
77753e4c44SMatthew Dillon reason = " (Template file missing)";
78753e4c44SMatthew Dillon }
791d6e00cdSMatthew Dillon free(buf);
801d6e00cdSMatthew Dillon
812074bc97SMatthew Dillon /*
822074bc97SMatthew Dillon * Check to see if the worker count changed and some
832074bc97SMatthew Dillon * template dirs are missing or out of date, and also if
842074bc97SMatthew Dillon * a new world was installed (via /bin/ls mtime).
852074bc97SMatthew Dillon */
862074bc97SMatthew Dillon asprintf(&buf, "%s/bin/ls", SystemPath);
872074bc97SMatthew Dillon if (stat(buf, &st) < 0)
882074bc97SMatthew Dillon dfatal_errno("Unable to locate %s", buf);
892074bc97SMatthew Dillon free(buf);
902074bc97SMatthew Dillon ls_mtime = st.st_mtime;
912074bc97SMatthew Dillon
922074bc97SMatthew Dillon for (n = 0; n < MaxWorkers; ++n) {
932074bc97SMatthew Dillon asprintf(&buf, "%s/bin.%03d/ls", BuildBase, n);
94753e4c44SMatthew Dillon if (stat(buf, &st) < 0 || st.st_mtime != ls_mtime) {
952074bc97SMatthew Dillon force = 1;
96753e4c44SMatthew Dillon reason = " (/bin/ls mtime mismatch)";
97753e4c44SMatthew Dillon }
982074bc97SMatthew Dillon free(buf);
992074bc97SMatthew Dillon }
1002074bc97SMatthew Dillon
101753e4c44SMatthew Dillon if (stat(goodbuf, &st) < 0) {
1021d6e00cdSMatthew Dillon force = 1;
103753e4c44SMatthew Dillon reason = " (.template.good file missing)";
104753e4c44SMatthew Dillon }
1051d6e00cdSMatthew Dillon }
1061d6e00cdSMatthew Dillon
107753e4c44SMatthew Dillon dlog(DLOG_ALL, "Check Template: %s%s\n",
108753e4c44SMatthew Dillon (force ? "Must-Create" : "Good"),
109753e4c44SMatthew Dillon reason);
1106fd67931SMatthew Dillon
1111d6e00cdSMatthew Dillon /*
1121d6e00cdSMatthew Dillon * Create the template
1131d6e00cdSMatthew Dillon */
1141d6e00cdSMatthew Dillon if (force) {
1158ec23ca1SMatthew Dillon remove(goodbuf); /* ignore exit code */
1168ec23ca1SMatthew Dillon
1171d6e00cdSMatthew Dillon rc = 0;
1188e25f19bSMatthew Dillon asprintf(&buf, "%s/mktemplate %s %s/Template",
1198e25f19bSMatthew Dillon SCRIPTPATH(SCRIPTDIR), SystemPath, BuildBase);
1208e25f19bSMatthew Dillon rc = system(buf);
1218e25f19bSMatthew Dillon if (rc)
1228e25f19bSMatthew Dillon dfatal("Command failed: %s\n", buf);
123a574cbf0SMatthew Dillon dlog(DLOG_ALL | DLOG_FILTER,
124a574cbf0SMatthew Dillon "Template - rc=%d running %s\n", rc, buf);
1258e25f19bSMatthew Dillon free(buf);
1261d6e00cdSMatthew Dillon
1271d6e00cdSMatthew Dillon /*
1281d6e00cdSMatthew Dillon * Make discrete copies of certain extremely heavily used
1291d6e00cdSMatthew Dillon * but small directories.
1301d6e00cdSMatthew Dillon */
1311d6e00cdSMatthew Dillon makeDiscreteCopies("$/bin", "/bin.%03d");
1321d6e00cdSMatthew Dillon makeDiscreteCopies("$/lib", "/lib.%03d");
1331d6e00cdSMatthew Dillon makeDiscreteCopies("$/libexec", "/libexec.%03d");
1341d6e00cdSMatthew Dillon makeDiscreteCopies("$/usr/bin", "/usr.bin.%03d");
1358e25f19bSMatthew Dillon
1368ec23ca1SMatthew Dillon /*
1378ec23ca1SMatthew Dillon * Mark the template good... ah, do a sync() to really
1388ec23ca1SMatthew Dillon * be sure that it can't get corrupted.
1398ec23ca1SMatthew Dillon */
1408ec23ca1SMatthew Dillon sync();
1418ec23ca1SMatthew Dillon fd = open(goodbuf, O_RDWR|O_CREAT|O_TRUNC, 0644);
1428ec23ca1SMatthew Dillon dassert_errno(fd >= 0, "could not create %s", goodbuf);
1438ec23ca1SMatthew Dillon close(fd);
1448ec23ca1SMatthew Dillon
145a574cbf0SMatthew Dillon dlog(DLOG_ALL | DLOG_FILTER, "Template - done\n");
1468ec23ca1SMatthew Dillon }
1478ec23ca1SMatthew Dillon free(goodbuf);
1488ec23ca1SMatthew Dillon
1496fd67931SMatthew Dillon return force;
1508e25f19bSMatthew Dillon }
1518e25f19bSMatthew Dillon
1528e25f19bSMatthew Dillon void
DoDestroyTemplate(void)1538e25f19bSMatthew Dillon DoDestroyTemplate(void)
1548e25f19bSMatthew Dillon {
1558e25f19bSMatthew Dillon struct stat st;
1568e25f19bSMatthew Dillon char *path;
1578e25f19bSMatthew Dillon char *buf;
1588e25f19bSMatthew Dillon int rc;
1598e25f19bSMatthew Dillon
1608e25f19bSMatthew Dillon /*
1618e25f19bSMatthew Dillon * NOTE: rm -rf safety, use a fixed name 'Template' to ensure we
1628e25f19bSMatthew Dillon * do not accidently blow something up.
1638e25f19bSMatthew Dillon */
1648e25f19bSMatthew Dillon asprintf(&path, "%s/Template", BuildBase);
1658e25f19bSMatthew Dillon if (stat(path, &st) == 0) {
1668e25f19bSMatthew Dillon asprintf(&buf, "chflags -R noschg %s; /bin/rm -rf %s",
1678e25f19bSMatthew Dillon path, path);
1688e25f19bSMatthew Dillon rc = system(buf);
1698e25f19bSMatthew Dillon if (rc)
1708e25f19bSMatthew Dillon dfatal("Command failed: %s (ignored)\n", buf);
1718e25f19bSMatthew Dillon free(buf);
1728e25f19bSMatthew Dillon }
1738e25f19bSMatthew Dillon free(path);
1748e25f19bSMatthew Dillon }
1758e25f19bSMatthew Dillon
1768e25f19bSMatthew Dillon /*
1778e25f19bSMatthew Dillon * Called by the worker support thread to install a new worker
1788e25f19bSMatthew Dillon * filesystem topology.
1798e25f19bSMatthew Dillon */
1808e25f19bSMatthew Dillon void
DoWorkerMounts(worker_t * work)1818e25f19bSMatthew Dillon DoWorkerMounts(worker_t *work)
1828e25f19bSMatthew Dillon {
1838e25f19bSMatthew Dillon char *buf;
1848e25f19bSMatthew Dillon int rc;
1858e25f19bSMatthew Dillon
1868e25f19bSMatthew Dillon /*
1878e25f19bSMatthew Dillon * Generate required mounts, domount() will mkdir() the target
1888e25f19bSMatthew Dillon * directory if necessary and prefix spath with SystemPath if
1898e25f19bSMatthew Dillon * it starts with $/
1908e25f19bSMatthew Dillon */
1913bd7e0a7SMatthew Dillon setNumaDomain(work->index);
1921d6e00cdSMatthew Dillon domount(work, TMPFS_RW, "dummy", "", NULL);
1938e25f19bSMatthew Dillon asprintf(&buf, "%s/usr", work->basedir);
1948e25f19bSMatthew Dillon if (mkdir(buf, 0755) != 0) {
1958e25f19bSMatthew Dillon fprintf(stderr, "Command failed: mkdir %s\n", buf);
1968e25f19bSMatthew Dillon ++work->mount_error;
1978e25f19bSMatthew Dillon }
19840dedc16SAntonio Huete Jimenez free(buf);
199*2b0cb817SMatthew Dillon asprintf(&buf, "%s/usr/packages", work->basedir);
200*2b0cb817SMatthew Dillon if (mkdir(buf, 0755) != 0) {
201*2b0cb817SMatthew Dillon fprintf(stderr, "Command failed: mkdir %s\n", buf);
202*2b0cb817SMatthew Dillon ++work->mount_error;
203*2b0cb817SMatthew Dillon }
204*2b0cb817SMatthew Dillon free(buf);
20540dedc16SAntonio Huete Jimenez
20649d2b1cbSMatthew Dillon domount(work, TMPFS_RW, "dummy", "/boot", NULL);
20749d2b1cbSMatthew Dillon
20849d2b1cbSMatthew Dillon asprintf(&buf, "%s/boot/modules.local", work->basedir);
20949d2b1cbSMatthew Dillon if (mkdir(buf, 0755) != 0) {
21049d2b1cbSMatthew Dillon fprintf(stderr, "Command failed: mkdir %s\n", buf);
21149d2b1cbSMatthew Dillon ++work->mount_error;
21249d2b1cbSMatthew Dillon }
21349d2b1cbSMatthew Dillon free(buf);
21449d2b1cbSMatthew Dillon
2151d6e00cdSMatthew Dillon domount(work, DEVFS_RW, "dummy", "/dev", NULL);
2168ec23ca1SMatthew Dillon domount(work, PROCFS_RO, "dummy", "/proc", NULL);
2171d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/bin", "/bin", "/bin.%03d");
2181d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/sbin", "/sbin", NULL);
2191d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/lib", "/lib", "/lib.%03d");
2201d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/libexec", "/libexec", "/libexec.%03d");
2211d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/usr/bin", "/usr/bin", "/usr.bin.%03d");
2221d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/usr/include", "/usr/include", NULL);
2231d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/usr/lib", "/usr/lib", NULL);
2241d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/usr/libdata", "/usr/libdata", NULL);
2251d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/usr/libexec", "/usr/libexec", NULL);
2261d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/usr/sbin", "/usr/sbin", NULL);
2271d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/usr/share", "/usr/share", NULL);
228a6361508SMatthew Dillon domount(work, TMPFS_RW_MED, "dummy", "/usr/local", NULL);
2291d6e00cdSMatthew Dillon domount(work, NULLFS_RO, "$/usr/games", "/usr/games", NULL);
230f4094b20SMatthew Dillon if (UseUsrSrc)
231f4094b20SMatthew Dillon domount(work, NULLFS_RO, "$/usr/src", "/usr/src", NULL);
2321d6e00cdSMatthew Dillon domount(work, NULLFS_RO, DPortsPath, "/xports", NULL);
2331d6e00cdSMatthew Dillon domount(work, NULLFS_RW, OptionsPath, "/options", NULL);
2341d6e00cdSMatthew Dillon domount(work, NULLFS_RW, PackagesPath, "/packages", NULL);
2351d6e00cdSMatthew Dillon domount(work, NULLFS_RW, DistFilesPath, "/distfiles", NULL);
2361d6e00cdSMatthew Dillon domount(work, TMPFS_RW_BIG, "dummy", "/construction", NULL);
2376fd67931SMatthew Dillon if (UseCCache)
238f4094b20SMatthew Dillon domount(work, NULLFS_RW, CCachePath, "/ccache", NULL);
2398e25f19bSMatthew Dillon
2408e25f19bSMatthew Dillon /*
2418e25f19bSMatthew Dillon * NOTE: Uses blah/. to prevent cp from creating 'Template' under
2428e25f19bSMatthew Dillon * work->basedir. We want to start with the content.
2438e25f19bSMatthew Dillon */
2448e25f19bSMatthew Dillon asprintf(&buf, "cp -Rp %s/Template/. %s", BuildBase, work->basedir);
2458e25f19bSMatthew Dillon rc = system(buf);
2468e25f19bSMatthew Dillon if (rc) {
2478e25f19bSMatthew Dillon fprintf(stderr, "Command failed: %s\n", buf);
2488e25f19bSMatthew Dillon ++work->accum_error;
2498e25f19bSMatthew Dillon snprintf(work->status, sizeof(work->status),
2508e25f19bSMatthew Dillon "Template copy failed");
2518e25f19bSMatthew Dillon }
2528e25f19bSMatthew Dillon free(buf);
2533bd7e0a7SMatthew Dillon setNumaDomain(-1);
2548e25f19bSMatthew Dillon }
2558e25f19bSMatthew Dillon
2568e25f19bSMatthew Dillon /*
2578e25f19bSMatthew Dillon * Called by the worker support thread to remove a worker
2588e25f19bSMatthew Dillon * filesystem topology.
259f4094b20SMatthew Dillon *
260f4094b20SMatthew Dillon * NOTE: No need to conditionalize UseUsrSrc, it doesn't hurt to
261f4094b20SMatthew Dillon * issue the umount() if it isn't mounted and it ensures that
262f4094b20SMatthew Dillon * everything is unmounted properly on cleanup if the state
263f4094b20SMatthew Dillon * changes.
2648e25f19bSMatthew Dillon */
2658e25f19bSMatthew Dillon void
DoWorkerUnmounts(worker_t * work)2668e25f19bSMatthew Dillon DoWorkerUnmounts(worker_t *work)
2678e25f19bSMatthew Dillon {
2688e25f19bSMatthew Dillon int retries;
2698e25f19bSMatthew Dillon
2703bd7e0a7SMatthew Dillon setNumaDomain(work->index);
2718e25f19bSMatthew Dillon work->mount_error = 0;
2728e25f19bSMatthew Dillon for (retries = 0; retries < 10; ++retries) {
2738ec23ca1SMatthew Dillon dounmount(work, "/proc");
2748e25f19bSMatthew Dillon dounmount(work, "/dev");
275f4094b20SMatthew Dillon dounmount(work, "/usr/src");
2768e25f19bSMatthew Dillon dounmount(work, "/usr/games");
2778e25f19bSMatthew Dillon dounmount(work, "/boot");
2788e25f19bSMatthew Dillon dounmount(work, "/usr/local");
2798e25f19bSMatthew Dillon dounmount(work, "/construction");
2806fd67931SMatthew Dillon dounmount(work, "/ccache"); /* in case of config change */
2818e25f19bSMatthew Dillon dounmount(work, "/distfiles");
2828e25f19bSMatthew Dillon dounmount(work, "/packages");
2838e25f19bSMatthew Dillon dounmount(work, "/options");
2848e25f19bSMatthew Dillon dounmount(work, "/xports");
2858e25f19bSMatthew Dillon dounmount(work, "/usr/share");
2868e25f19bSMatthew Dillon dounmount(work, "/usr/sbin");
2878e25f19bSMatthew Dillon dounmount(work, "/usr/libexec");
2888e25f19bSMatthew Dillon dounmount(work, "/usr/libdata");
2898e25f19bSMatthew Dillon dounmount(work, "/usr/lib");
2908e25f19bSMatthew Dillon dounmount(work, "/usr/include");
2918e25f19bSMatthew Dillon dounmount(work, "/usr/bin");
2928e25f19bSMatthew Dillon dounmount(work, "/libexec");
2938e25f19bSMatthew Dillon dounmount(work, "/lib");
2948e25f19bSMatthew Dillon dounmount(work, "/sbin");
2958e25f19bSMatthew Dillon dounmount(work, "/bin");
2968e25f19bSMatthew Dillon dounmount(work, "");
2978e25f19bSMatthew Dillon if (work->mount_error == 0)
2988e25f19bSMatthew Dillon break;
2998e25f19bSMatthew Dillon sleep(5);
3008e25f19bSMatthew Dillon work->mount_error = 0;
3018e25f19bSMatthew Dillon }
3028e25f19bSMatthew Dillon if (work->mount_error) {
3038e25f19bSMatthew Dillon ++work->accum_error;
3048e25f19bSMatthew Dillon snprintf(work->status, sizeof(work->status),
3058e25f19bSMatthew Dillon "Unable to unmount slot");
3068e25f19bSMatthew Dillon }
3073bd7e0a7SMatthew Dillon setNumaDomain(-1);
3088e25f19bSMatthew Dillon }
3098e25f19bSMatthew Dillon
3108e25f19bSMatthew Dillon static
3118e25f19bSMatthew Dillon void
domount(worker_t * work,int type,const char * spath,const char * dpath,const char * discretefmt)3121d6e00cdSMatthew Dillon domount(worker_t *work, int type, const char *spath, const char *dpath,
3131d6e00cdSMatthew Dillon const char *discretefmt)
3148e25f19bSMatthew Dillon {
3158e25f19bSMatthew Dillon const char *sbase;
3168e25f19bSMatthew Dillon const char *rwstr;
3178e25f19bSMatthew Dillon const char *optstr;
318223eb4a7SAntonio Huete Jimenez const char *typestr;
319aeecca07SMatthew Dillon const char *debug;
3208e25f19bSMatthew Dillon struct stat st;
3218e25f19bSMatthew Dillon char *buf;
3221d6e00cdSMatthew Dillon char *tmp;
3238e25f19bSMatthew Dillon int rc;
3248e25f19bSMatthew Dillon
3258e25f19bSMatthew Dillon /*
3268e25f19bSMatthew Dillon * Make target directory if necessary. This must occur in-order
3278e25f19bSMatthew Dillon * since directories may have to be created under prior mounts
3288e25f19bSMatthew Dillon * in the sequence.
3298e25f19bSMatthew Dillon */
3308e25f19bSMatthew Dillon asprintf(&buf, "%s%s", work->basedir, dpath);
3318e25f19bSMatthew Dillon if (stat(buf, &st) != 0) {
3328e25f19bSMatthew Dillon if (mkdir(buf, 0755) != 0) {
3338e25f19bSMatthew Dillon fprintf(stderr, "Command failed: mkdir %s\n", buf);
3348e25f19bSMatthew Dillon ++work->mount_error;
3358e25f19bSMatthew Dillon }
3368e25f19bSMatthew Dillon }
3378e25f19bSMatthew Dillon free(buf);
3388e25f19bSMatthew Dillon
3398e25f19bSMatthew Dillon /*
3408e25f19bSMatthew Dillon * Setup for mount arguments
3418e25f19bSMatthew Dillon */
3428e25f19bSMatthew Dillon rwstr = (type & MOUNT_TYPE_RW) ? "rw" : "ro";
3438e25f19bSMatthew Dillon optstr = "";
344223eb4a7SAntonio Huete Jimenez typestr = "";
3458e25f19bSMatthew Dillon
3468e25f19bSMatthew Dillon switch(type & MOUNT_TYPE_MASK) {
3478e25f19bSMatthew Dillon case MOUNT_TYPE_TMPFS:
348aeecca07SMatthew Dillon /*
349aeecca07SMatthew Dillon * When creating a tmpfs filesystem, make sure the big ones
350aeecca07SMatthew Dillon * requested are big enough for the worst-case dport (which
351aeecca07SMatthew Dillon * is usually chromium). If debugging is turned on, its even
352aeecca07SMatthew Dillon * worse. You'd better have enough swap!
353aeecca07SMatthew Dillon */
354aeecca07SMatthew Dillon debug = getbuildenv("WITH_DEBUG");
355223eb4a7SAntonio Huete Jimenez typestr = "tmpfs";
3568e25f19bSMatthew Dillon if (type & MOUNT_TYPE_BIG)
357aeecca07SMatthew Dillon optstr = debug ? " -o size=128g" : " -o size=64g";
358a6361508SMatthew Dillon else if (type & MOUNT_TYPE_MED)
359a6361508SMatthew Dillon optstr = debug ? " -o size=32g" : " -o size=16g";
3608e25f19bSMatthew Dillon else
361223eb4a7SAntonio Huete Jimenez optstr = " -o size=16g";
3628e25f19bSMatthew Dillon break;
3638e25f19bSMatthew Dillon case MOUNT_TYPE_NULLFS:
364223eb4a7SAntonio Huete Jimenez #if defined(__DragonFly__)
365223eb4a7SAntonio Huete Jimenez typestr = "null";
366223eb4a7SAntonio Huete Jimenez #else
367223eb4a7SAntonio Huete Jimenez typestr = "nullfs";
368223eb4a7SAntonio Huete Jimenez #endif
3698e25f19bSMatthew Dillon break;
3708e25f19bSMatthew Dillon case MOUNT_TYPE_DEVFS:
371223eb4a7SAntonio Huete Jimenez typestr = "devfs";
3728e25f19bSMatthew Dillon break;
3738ec23ca1SMatthew Dillon case MOUNT_TYPE_PROCFS:
374223eb4a7SAntonio Huete Jimenez typestr = "procfs";
3758ec23ca1SMatthew Dillon break;
3768e25f19bSMatthew Dillon default:
3778e25f19bSMatthew Dillon dfatal("Illegal mount type: %08x", type);
3788e25f19bSMatthew Dillon /* NOT REACHED */
3798e25f19bSMatthew Dillon break;
3808e25f19bSMatthew Dillon }
3818e25f19bSMatthew Dillon
3828e25f19bSMatthew Dillon /*
3838e25f19bSMatthew Dillon * Prefix spath
3848e25f19bSMatthew Dillon */
3851d6e00cdSMatthew Dillon if (discretefmt) {
3861d6e00cdSMatthew Dillon sbase = BuildBase;
3871d6e00cdSMatthew Dillon asprintf(&tmp, discretefmt, work->index);
3881d6e00cdSMatthew Dillon spath = tmp;
3891d6e00cdSMatthew Dillon } else {
3908e25f19bSMatthew Dillon if (spath[0] == '$') {
3918e25f19bSMatthew Dillon ++spath;
3928e25f19bSMatthew Dillon sbase = SystemPath;
3931d6e00cdSMatthew Dillon if (strcmp(sbase, "/") == 0)
3941d6e00cdSMatthew Dillon ++sbase;
3958e25f19bSMatthew Dillon } else {
3968e25f19bSMatthew Dillon sbase = "";
3978e25f19bSMatthew Dillon }
3981d6e00cdSMatthew Dillon tmp = NULL;
3991d6e00cdSMatthew Dillon }
400223eb4a7SAntonio Huete Jimenez asprintf(&buf, "%s%s -t %s -o %s %s%s %s%s",
401223eb4a7SAntonio Huete Jimenez MOUNT_BINARY, optstr, typestr, rwstr,
4028e25f19bSMatthew Dillon sbase, spath, work->basedir, dpath);
4038e25f19bSMatthew Dillon rc = system(buf);
4048e25f19bSMatthew Dillon if (rc) {
4058e25f19bSMatthew Dillon fprintf(stderr, "Command failed: %s\n", buf);
4068e25f19bSMatthew Dillon ++work->mount_error;
4078e25f19bSMatthew Dillon }
4088e25f19bSMatthew Dillon free(buf);
4091d6e00cdSMatthew Dillon if (tmp)
4101d6e00cdSMatthew Dillon free(tmp);
4118e25f19bSMatthew Dillon }
4128e25f19bSMatthew Dillon
4138e25f19bSMatthew Dillon static
4148e25f19bSMatthew Dillon void
dounmount(worker_t * work,const char * rpath)4158e25f19bSMatthew Dillon dounmount(worker_t *work, const char *rpath)
4168e25f19bSMatthew Dillon {
4178e25f19bSMatthew Dillon char *buf;
4188e25f19bSMatthew Dillon
4198e25f19bSMatthew Dillon asprintf(&buf, "%s%s", work->basedir, rpath);
4208e25f19bSMatthew Dillon if (unmount(buf, 0) < 0) {
4218e25f19bSMatthew Dillon switch(errno) {
42268dc2eeaSMatthew Dillon case EPERM: /* This is probably fatal later on in mount */
42368dc2eeaSMatthew Dillon case ENOENT: /* Expected if mount already gone */
42468dc2eeaSMatthew Dillon case EINVAL: /* Expected if mount already gone (maybe) */
4258e25f19bSMatthew Dillon break;
4268e25f19bSMatthew Dillon default:
4271d6e00cdSMatthew Dillon fprintf(stderr, "Cannot umount %s (%s)\n",
4281d6e00cdSMatthew Dillon buf, strerror(errno));
4298e25f19bSMatthew Dillon ++work->mount_error;
4308e25f19bSMatthew Dillon break;
4318e25f19bSMatthew Dillon }
4328e25f19bSMatthew Dillon }
4338e25f19bSMatthew Dillon free(buf);
4348e25f19bSMatthew Dillon }
4351d6e00cdSMatthew Dillon
4361d6e00cdSMatthew Dillon static
4371d6e00cdSMatthew Dillon void
makeDiscreteCopies(const char * spath,const char * discretefmt)4381d6e00cdSMatthew Dillon makeDiscreteCopies(const char *spath, const char *discretefmt)
4391d6e00cdSMatthew Dillon {
4401d6e00cdSMatthew Dillon char *src;
4411d6e00cdSMatthew Dillon char *dst;
4421d6e00cdSMatthew Dillon char *buf;
4431d6e00cdSMatthew Dillon struct stat st;
4441d6e00cdSMatthew Dillon int i;
4451d6e00cdSMatthew Dillon int rc;
4461d6e00cdSMatthew Dillon
4471d6e00cdSMatthew Dillon for (i = 0; i < MaxWorkers; ++i) {
4483bd7e0a7SMatthew Dillon setNumaDomain(i);
4491d6e00cdSMatthew Dillon if (spath[0] == '$') {
4501d6e00cdSMatthew Dillon if (strcmp(SystemPath, "/") == 0)
4511d6e00cdSMatthew Dillon asprintf(&src, "%s%s",
4521d6e00cdSMatthew Dillon SystemPath + 1, spath + 1);
4531d6e00cdSMatthew Dillon else
4541d6e00cdSMatthew Dillon asprintf(&src, "%s%s",
4551d6e00cdSMatthew Dillon SystemPath, spath + 1);
4561d6e00cdSMatthew Dillon } else {
4571d6e00cdSMatthew Dillon src = strdup(spath);
4581d6e00cdSMatthew Dillon }
4591d6e00cdSMatthew Dillon asprintf(&buf, discretefmt, i);
4601d6e00cdSMatthew Dillon asprintf(&dst, "%s%s", BuildBase, buf);
4611d6e00cdSMatthew Dillon free(buf);
4628d9409b8SMatthew Dillon
4631d6e00cdSMatthew Dillon if (stat(dst, &st) < 0) {
4646fd67931SMatthew Dillon if (mkdir(dst, 0555) < 0) {
4656fd67931SMatthew Dillon dlog(DLOG_ALL, "Template - mkdir %s failed\n",
4666fd67931SMatthew Dillon dst);
4678d9409b8SMatthew Dillon dfatal_errno("Cannot mkdir %s:", dst);
4686fd67931SMatthew Dillon }
4696fd67931SMatthew Dillon }
4708ec23ca1SMatthew Dillon asprintf(&buf, "chflags -R noschg %s; "
4718ec23ca1SMatthew Dillon "rm -rf %s; "
4728ec23ca1SMatthew Dillon "cp -Rp %s/. %s",
4738ec23ca1SMatthew Dillon dst, dst, src, dst);
4741d6e00cdSMatthew Dillon rc = system(buf);
475a574cbf0SMatthew Dillon dlog(DLOG_ALL | DLOG_FILTER,
476a574cbf0SMatthew Dillon "Template - rc=%d running %s\n", rc, buf);
4771d6e00cdSMatthew Dillon if (rc)
4781d6e00cdSMatthew Dillon dfatal("Command failed: %s", buf);
4791d6e00cdSMatthew Dillon free(buf);
4801d6e00cdSMatthew Dillon free(src);
4811d6e00cdSMatthew Dillon free(dst);
4823bd7e0a7SMatthew Dillon setNumaDomain(-1);
4831d6e00cdSMatthew Dillon }
4841d6e00cdSMatthew Dillon }
485