Print this page
PSARC 2008/290 lofi mount
6384817 Need persistent lofi based mounts and direct mount(1m) support for lofi


   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "@(#)zoneadm.c  1.64    08/01/14 SMI"
  28 
  29 /*
  30  * zoneadm is a command interpreter for zone administration.  It is all in
  31  * C (i.e., no lex/yacc), and all the argument passing is argc/argv based.
  32  * main() calls parse_and_run() which calls cmd_match(), then invokes the
  33  * appropriate command's handler function.  The rest of the program is the
  34  * handler functions and their helper functions.
  35  *
  36  * Some of the helper functions are used largely to simplify I18N: reducing
  37  * the need for translation notes.  This is particularly true of many of
  38  * the zerror() calls: doing e.g. zerror(gettext("%s failed"), "foo") rather
  39  * than zerror(gettext("foo failed")) with a translation note indicating
  40  * that "foo" need not be translated.
  41  */
  42 
  43 #include <stdio.h>
  44 #include <errno.h>
  45 #include <unistd.h>
  46 #include <signal.h>
  47 #include <stdarg.h>


2420                          * not be translated.
2421                          */
2422                         (void) fprintf(stderr, gettext("cannot verify "
2423                             "inherit-pkg-dir %s: NFS mounted file system.\n"
2424                             "\tA local file system must be used.\n"),
2425                             fstab.zone_fs_dir);
2426                         return_code = Z_ERR;
2427                 }
2428         }
2429         (void) zonecfg_endipdent(handle);
2430 
2431         return (return_code);
2432 }
2433 
2434 /*
2435  * Verify that the special device/file system exists and is valid.
2436  */
2437 static int
2438 verify_fs_special(struct zone_fstab *fstab)
2439 {
2440         struct stat st;
2441 
2442         /*
2443          * This validation is really intended for standard zone administration.
2444          * If we are in a mini-root or some other upgrade situation where
2445          * we are using the scratch zone, just by-pass this.
2446          */
2447         if (zonecfg_in_alt_root())
2448                 return (Z_OK);
2449 
2450         if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0)
2451                 return (verify_fs_zfs(fstab));
2452 
2453         if (stat(fstab->zone_fs_special, &st) != 0) {
2454                 (void) fprintf(stderr, gettext("could not verify fs "
2455                     "%s: could not access %s: %s\n"), fstab->zone_fs_dir,
2456                     fstab->zone_fs_special, strerror(errno));
2457                 return (Z_ERR);
2458         }
2459 
2460         if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) {
2461                 /*
2462                  * TRANSLATION_NOTE
2463                  * fs and NFS are literals that should
2464                  * not be translated.
2465                  */
2466                 (void) fprintf(stderr, gettext("cannot verify "
2467                     "fs %s: NFS mounted file system.\n"
2468                     "\tA local file system must be used.\n"),
2469                     fstab->zone_fs_special);
2470                 return (Z_ERR);
2471         }
2472 
2473         return (Z_OK);
2474 }
2475 
2476 static int











2477 verify_filesystems(zone_dochandle_t handle)
2478 {
2479         int return_code = Z_OK;
2480         struct zone_fstab fstab;
2481         char cmdbuf[MAXPATHLEN];
2482         struct stat st;
2483 
2484         /*
2485          * No need to verify inherit-pkg-dir fs types, as their type is
2486          * implicitly lofs, which is known.  Therefore, the types are only
2487          * verified for regular file systems below.
2488          *
2489          * Since the actual mount point is not known until the dependent mounts
2490          * are performed, we don't attempt any path validation here: that will
2491          * happen later when zoneadmd actually does the mounts.
2492          */
2493         if (zonecfg_setfsent(handle) != Z_OK) {
2494                 (void) fprintf(stderr, gettext("could not verify file systems: "
2495                     "unable to enumerate mounts\n"));
2496                 return (Z_ERR);


2512                             "type %s is too long.\n"), fstab.zone_fs_dir,
2513                             fstab.zone_fs_type);
2514                         return_code = Z_ERR;
2515                         goto next_fs;
2516                 }
2517                 if (stat(cmdbuf, &st) != 0) {
2518                         (void) fprintf(stderr, gettext("could not verify fs "
2519                             "%s: could not access %s: %s\n"), fstab.zone_fs_dir,
2520                             cmdbuf, strerror(errno));
2521                         return_code = Z_ERR;
2522                         goto next_fs;
2523                 }
2524                 if (!S_ISREG(st.st_mode)) {
2525                         (void) fprintf(stderr, gettext("could not verify fs "
2526                             "%s: %s is not a regular file\n"),
2527                             fstab.zone_fs_dir, cmdbuf);
2528                         return_code = Z_ERR;
2529                         goto next_fs;
2530                 }
2531                 /*
2532                  * Verify /usr/lib/fs/<fstype>/fsck exists iff zone_fs_raw is
2533                  * set.


2534                  */
2535                 if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/fsck",
2536                     fstab.zone_fs_type) > sizeof (cmdbuf)) {
2537                         (void) fprintf(stderr, gettext("cannot verify fs %s: "
2538                             "type %s is too long.\n"), fstab.zone_fs_dir,
2539                             fstab.zone_fs_type);
2540                         return_code = Z_ERR;
2541                         goto next_fs;
2542                 }
2543                 if (fstab.zone_fs_raw[0] == '\0' && stat(cmdbuf, &st) == 0) {
2544                         (void) fprintf(stderr, gettext("could not verify fs "
2545                             "%s: must specify 'raw' device for %s "
2546                             "file systems\n"),
2547                             fstab.zone_fs_dir, fstab.zone_fs_type);
2548                         return_code = Z_ERR;
2549                         goto next_fs;
2550                 }
2551                 if (fstab.zone_fs_raw[0] != '\0' &&
2552                     (stat(cmdbuf, &st) != 0 || !S_ISREG(st.st_mode))) {
2553                         (void) fprintf(stderr, gettext("cannot verify fs %s: "
2554                             "'raw' device specified but "
2555                             "no fsck executable exists for %s\n"),
2556                             fstab.zone_fs_dir, fstab.zone_fs_type);
2557                         return_code = Z_ERR;









2558                         goto next_fs;
2559                 }
2560 
2561                 /* Verify fs_special. */
2562                 if ((return_code = verify_fs_special(&fstab)) != Z_OK)
2563                         goto next_fs;
2564 
2565                 /* Verify fs_raw. */
2566                 if (fstab.zone_fs_raw[0] != '\0' &&
2567                     stat(fstab.zone_fs_raw, &st) != 0) {
2568                         /*
2569                          * TRANSLATION_NOTE
2570                          * fs is a literal that should not be translated.
2571                          */
2572                         (void) fprintf(stderr, gettext("could not verify fs "
2573                             "%s: could not access %s: %s\n"), fstab.zone_fs_dir,
2574                             fstab.zone_fs_raw, strerror(errno));
2575                         return_code = Z_ERR;
2576                         goto next_fs;
2577                 }




   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #pragma ident   "@(#)zoneadm.c  1.65    08/05/07 SMI"
  28 
  29 /*
  30  * zoneadm is a command interpreter for zone administration.  It is all in
  31  * C (i.e., no lex/yacc), and all the argument passing is argc/argv based.
  32  * main() calls parse_and_run() which calls cmd_match(), then invokes the
  33  * appropriate command's handler function.  The rest of the program is the
  34  * handler functions and their helper functions.
  35  *
  36  * Some of the helper functions are used largely to simplify I18N: reducing
  37  * the need for translation notes.  This is particularly true of many of
  38  * the zerror() calls: doing e.g. zerror(gettext("%s failed"), "foo") rather
  39  * than zerror(gettext("foo failed")) with a translation note indicating
  40  * that "foo" need not be translated.
  41  */
  42 
  43 #include <stdio.h>
  44 #include <errno.h>
  45 #include <unistd.h>
  46 #include <signal.h>
  47 #include <stdarg.h>


2420                          * not be translated.
2421                          */
2422                         (void) fprintf(stderr, gettext("cannot verify "
2423                             "inherit-pkg-dir %s: NFS mounted file system.\n"
2424                             "\tA local file system must be used.\n"),
2425                             fstab.zone_fs_dir);
2426                         return_code = Z_ERR;
2427                 }
2428         }
2429         (void) zonecfg_endipdent(handle);
2430 
2431         return (return_code);
2432 }
2433 
2434 /*
2435  * Verify that the special device/file system exists and is valid.
2436  */
2437 static int
2438 verify_fs_special(struct zone_fstab *fstab)
2439 {
2440         struct stat64 st;
2441 
2442         /*
2443          * This validation is really intended for standard zone administration.
2444          * If we are in a mini-root or some other upgrade situation where
2445          * we are using the scratch zone, just by-pass this.
2446          */
2447         if (zonecfg_in_alt_root())
2448                 return (Z_OK);
2449 
2450         if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0)
2451                 return (verify_fs_zfs(fstab));
2452 
2453         if (stat64(fstab->zone_fs_special, &st) != 0) {
2454                 (void) fprintf(stderr, gettext("could not verify fs "
2455                     "%s: could not access %s: %s\n"), fstab->zone_fs_dir,
2456                     fstab->zone_fs_special, strerror(errno));
2457                 return (Z_ERR);
2458         }
2459 
2460         if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) {
2461                 /*
2462                  * TRANSLATION_NOTE
2463                  * fs and NFS are literals that should
2464                  * not be translated.
2465                  */
2466                 (void) fprintf(stderr, gettext("cannot verify "
2467                     "fs %s: NFS mounted file system.\n"
2468                     "\tA local file system must be used.\n"),
2469                     fstab->zone_fs_special);
2470                 return (Z_ERR);
2471         }
2472 
2473         return (Z_OK);
2474 }
2475 
2476 static int
2477 isregfile(const char *path)
2478 {
2479         struct stat64 st;
2480 
2481         if (stat64(path, &st) == -1)
2482                 return (-1);
2483 
2484         return (S_ISREG(st.st_mode));
2485 }
2486 
2487 static int
2488 verify_filesystems(zone_dochandle_t handle)
2489 {
2490         int return_code = Z_OK;
2491         struct zone_fstab fstab;
2492         char cmdbuf[MAXPATHLEN];
2493         struct stat st;
2494 
2495         /*
2496          * No need to verify inherit-pkg-dir fs types, as their type is
2497          * implicitly lofs, which is known.  Therefore, the types are only
2498          * verified for regular file systems below.
2499          *
2500          * Since the actual mount point is not known until the dependent mounts
2501          * are performed, we don't attempt any path validation here: that will
2502          * happen later when zoneadmd actually does the mounts.
2503          */
2504         if (zonecfg_setfsent(handle) != Z_OK) {
2505                 (void) fprintf(stderr, gettext("could not verify file systems: "
2506                     "unable to enumerate mounts\n"));
2507                 return (Z_ERR);


2523                             "type %s is too long.\n"), fstab.zone_fs_dir,
2524                             fstab.zone_fs_type);
2525                         return_code = Z_ERR;
2526                         goto next_fs;
2527                 }
2528                 if (stat(cmdbuf, &st) != 0) {
2529                         (void) fprintf(stderr, gettext("could not verify fs "
2530                             "%s: could not access %s: %s\n"), fstab.zone_fs_dir,
2531                             cmdbuf, strerror(errno));
2532                         return_code = Z_ERR;
2533                         goto next_fs;
2534                 }
2535                 if (!S_ISREG(st.st_mode)) {
2536                         (void) fprintf(stderr, gettext("could not verify fs "
2537                             "%s: %s is not a regular file\n"),
2538                             fstab.zone_fs_dir, cmdbuf);
2539                         return_code = Z_ERR;
2540                         goto next_fs;
2541                 }
2542                 /*
2543                  * If zone_fs_raw is set, verify that there's an fsck
2544                  * binary for it.  If zone_fs_raw is not set, and it's
2545                  * not a regular file (lofi mount), and there's an fsck
2546                  * binary for it, complain.
2547                  */
2548                 if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/fsck",
2549                     fstab.zone_fs_type) > sizeof (cmdbuf)) {
2550                         (void) fprintf(stderr, gettext("cannot verify fs %s: "
2551                             "type %s is too long.\n"), fstab.zone_fs_dir,
2552                             fstab.zone_fs_type);
2553                         return_code = Z_ERR;
2554                         goto next_fs;
2555                 }








2556                 if (fstab.zone_fs_raw[0] != '\0' &&
2557                     (stat(cmdbuf, &st) != 0 || !S_ISREG(st.st_mode))) {
2558                         (void) fprintf(stderr, gettext("cannot verify fs %s: "
2559                             "'raw' device specified but "
2560                             "no fsck executable exists for %s\n"),
2561                             fstab.zone_fs_dir, fstab.zone_fs_type);
2562                         return_code = Z_ERR;
2563                         goto next_fs;
2564                 } else if (fstab.zone_fs_raw[0] == '\0' &&
2565                     stat(cmdbuf, &st) == 0 &&
2566                     isregfile(fstab.zone_fs_special) != 1) {
2567                         (void) fprintf(stderr, gettext("could not verify fs "
2568                             "%s: must specify 'raw' device for %s "
2569                             "file systems\n"),
2570                             fstab.zone_fs_dir, fstab.zone_fs_type);
2571                         return_code = Z_ERR;
2572                         goto next_fs;
2573                 }
2574 
2575                 /* Verify fs_special. */
2576                 if ((return_code = verify_fs_special(&fstab)) != Z_OK)
2577                         goto next_fs;
2578 
2579                 /* Verify fs_raw. */
2580                 if (fstab.zone_fs_raw[0] != '\0' &&
2581                     stat(fstab.zone_fs_raw, &st) != 0) {
2582                         /*
2583                          * TRANSLATION_NOTE
2584                          * fs is a literal that should not be translated.
2585                          */
2586                         (void) fprintf(stderr, gettext("could not verify fs "
2587                             "%s: could not access %s: %s\n"), fstab.zone_fs_dir,
2588                             fstab.zone_fs_raw, strerror(errno));
2589                         return_code = Z_ERR;
2590                         goto next_fs;
2591                 }