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   "@(#)vplat.c    1.60    08/04/08 SMI"
  28 
  29 /*
  30  * This module contains functions used to bring up and tear down the
  31  * Virtual Platform: [un]mounting file-systems, [un]plumbing network
  32  * interfaces, [un]configuring devices, establishing resource controls,
  33  * and creating/destroying the zone in the kernel.  These actions, on
  34  * the way up, ready the zone; on the way down, they halt the zone.
  35  * See the much longer block comment at the beginning of zoneadmd.c
  36  * for a bigger picture of how the whole program functions.
  37  *
  38  * This module also has primary responsibility for the layout of "scratch
  39  * zones."  These are mounted, but inactive, zones that are used during
  40  * operating system upgrade and potentially other administrative action.  The
  41  * scratch zone environment is similar to the miniroot environment.  The zone's
  42  * actual root is mounted read-write on /a, and the standard paths (/usr,
  43  * /sbin, /lib) all lead to read-only copies of the running system's binaries.
  44  * This allows the administrative tools to manipulate the zone using "-R /a"
  45  * without relying on any binaries in the zone itself.
  46  *
  47  * If the scratch zone is on an alternate root (Live Upgrade [LU] boot


 787 
 788                 _exit(ZEXIT_EXEC);
 789         } else {
 790                 (void) waitpid(child_pid, &child_status, 0);
 791         }
 792 
 793         if (WIFSIGNALED(child_status)) {
 794                 zerror(zlogp, B_FALSE, "%s unexpectedly terminated due to "
 795                     "signal %d", path, WTERMSIG(child_status));
 796                 return (-1);
 797         }
 798         assert(WIFEXITED(child_status));
 799         if (WEXITSTATUS(child_status) == ZEXIT_EXEC) {
 800                 zerror(zlogp, B_FALSE, "failed to exec %s", path);
 801                 return (-1);
 802         }
 803         return (WEXITSTATUS(child_status));
 804 }
 805 
 806 static int











 807 dofsck(zlog_t *zlogp, const char *fstype, const char *rawdev)
 808 {
 809         char cmdbuf[MAXPATHLEN];
 810         char *argv[4];
 811         int status;
 812 
 813         /*
 814          * We could alternatively have called /usr/sbin/fsck -F <fstype>, but
 815          * that would cost us an extra fork/exec without buying us anything.
 816          */
 817         if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/fsck", fstype)
 818             >= sizeof (cmdbuf)) {
 819                 zerror(zlogp, B_FALSE, "file-system type %s too long", fstype);
 820                 return (-1);
 821         }
 822 






 823         argv[0] = "fsck";
 824         argv[1] = "-m";
 825         argv[2] = (char *)rawdev;
 826         argv[3] = NULL;
 827 
 828         status = forkexec(zlogp, cmdbuf, argv);
 829         if (status == 0 || status == -1)
 830                 return (status);
 831         zerror(zlogp, B_FALSE, "fsck of '%s' failed with exit status %d; "
 832             "run fsck manually", rawdev, status);
 833         return (-1);
 834 }
 835 
 836 static int
 837 domount(zlog_t *zlogp, const char *fstype, const char *opts,
 838     const char *special, const char *directory)
 839 {
 840         char cmdbuf[MAXPATHLEN];
 841         char *argv[6];
 842         int status;


1244                          * of the device instead of a direct mount
1245                          */
1246                         if (check_lofs_needed(zlogp, fsptr) == -1)
1247                                 return (-1);
1248                 } else if (strcmp(fsptr->zone_fs_type, MNTTYPE_LOFS) == 0) {
1249                         /*
1250                          * For lofs mounts, the special node is inside the
1251                          * alternate root.  We need lofs resolution for
1252                          * this case in order to get at the underlying
1253                          * read-write path.
1254                          */
1255                         resolve_lofs(zlogp, fsptr->zone_fs_special,
1256                             sizeof (fsptr->zone_fs_special));
1257                 }
1258         }
1259 
1260         /*
1261          * Run 'fsck -m' if there's a device to fsck.
1262          */
1263         if (fsptr->zone_fs_raw[0] != '\0' &&
1264             dofsck(zlogp, fsptr->zone_fs_type, fsptr->zone_fs_raw) != 0)
1265                 return (-1);




1266 
1267         /*
1268          * Build up mount option string.
1269          */
1270         optstr[0] = '\0';
1271         if (fsptr->zone_fs_options != NULL) {
1272                 (void) strlcpy(optstr, fsptr->zone_fs_options->zone_fsopt_opt,
1273                     sizeof (optstr));
1274                 for (optptr = fsptr->zone_fs_options->zone_fsopt_next;
1275                     optptr != NULL; optptr = optptr->zone_fsopt_next) {
1276                         (void) strlcat(optstr, ",", sizeof (optstr));
1277                         (void) strlcat(optstr, optptr->zone_fsopt_opt,
1278                             sizeof (optstr));
1279                 }
1280         }
1281 
1282         if ((rv = domount(zlogp, fsptr->zone_fs_type, optstr,
1283             fsptr->zone_fs_special, path)) != 0)
1284                 return (rv);
1285 




   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   "@(#)vplat.c    1.61    08/05/07 SMI"
  28 
  29 /*
  30  * This module contains functions used to bring up and tear down the
  31  * Virtual Platform: [un]mounting file-systems, [un]plumbing network
  32  * interfaces, [un]configuring devices, establishing resource controls,
  33  * and creating/destroying the zone in the kernel.  These actions, on
  34  * the way up, ready the zone; on the way down, they halt the zone.
  35  * See the much longer block comment at the beginning of zoneadmd.c
  36  * for a bigger picture of how the whole program functions.
  37  *
  38  * This module also has primary responsibility for the layout of "scratch
  39  * zones."  These are mounted, but inactive, zones that are used during
  40  * operating system upgrade and potentially other administrative action.  The
  41  * scratch zone environment is similar to the miniroot environment.  The zone's
  42  * actual root is mounted read-write on /a, and the standard paths (/usr,
  43  * /sbin, /lib) all lead to read-only copies of the running system's binaries.
  44  * This allows the administrative tools to manipulate the zone using "-R /a"
  45  * without relying on any binaries in the zone itself.
  46  *
  47  * If the scratch zone is on an alternate root (Live Upgrade [LU] boot


 787 
 788                 _exit(ZEXIT_EXEC);
 789         } else {
 790                 (void) waitpid(child_pid, &child_status, 0);
 791         }
 792 
 793         if (WIFSIGNALED(child_status)) {
 794                 zerror(zlogp, B_FALSE, "%s unexpectedly terminated due to "
 795                     "signal %d", path, WTERMSIG(child_status));
 796                 return (-1);
 797         }
 798         assert(WIFEXITED(child_status));
 799         if (WEXITSTATUS(child_status) == ZEXIT_EXEC) {
 800                 zerror(zlogp, B_FALSE, "failed to exec %s", path);
 801                 return (-1);
 802         }
 803         return (WEXITSTATUS(child_status));
 804 }
 805 
 806 static int
 807 isregfile(const char *path)
 808 {
 809         struct stat64 st;
 810 
 811         if (stat64(path, &st) == -1)
 812                 return (-1);
 813 
 814         return (S_ISREG(st.st_mode));
 815 }
 816 
 817 static int
 818 dofsck(zlog_t *zlogp, const char *fstype, const char *rawdev)
 819 {
 820         char cmdbuf[MAXPATHLEN];
 821         char *argv[4];
 822         int status;
 823 
 824         /*
 825          * We could alternatively have called /usr/sbin/fsck -F <fstype>, but
 826          * that would cost us an extra fork/exec without buying us anything.
 827          */
 828         if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/fsck", fstype)
 829             >= sizeof (cmdbuf)) {
 830                 zerror(zlogp, B_FALSE, "file-system type %s too long", fstype);
 831                 return (-1);
 832         }
 833 
 834         /*
 835          * If it doesn't exist, that's OK: we verified this previously.
 836          */
 837         if (isregfile(cmdbuf) == -1)
 838                 return (0);
 839 
 840         argv[0] = "fsck";
 841         argv[1] = "-m";
 842         argv[2] = (char *)rawdev;
 843         argv[3] = NULL;
 844 
 845         status = forkexec(zlogp, cmdbuf, argv);
 846         if (status == 0 || status == -1)
 847                 return (status);
 848         zerror(zlogp, B_FALSE, "fsck of '%s' failed with exit status %d; "
 849             "run fsck manually", rawdev, status);
 850         return (-1);
 851 }
 852 
 853 static int
 854 domount(zlog_t *zlogp, const char *fstype, const char *opts,
 855     const char *special, const char *directory)
 856 {
 857         char cmdbuf[MAXPATHLEN];
 858         char *argv[6];
 859         int status;


1261                          * of the device instead of a direct mount
1262                          */
1263                         if (check_lofs_needed(zlogp, fsptr) == -1)
1264                                 return (-1);
1265                 } else if (strcmp(fsptr->zone_fs_type, MNTTYPE_LOFS) == 0) {
1266                         /*
1267                          * For lofs mounts, the special node is inside the
1268                          * alternate root.  We need lofs resolution for
1269                          * this case in order to get at the underlying
1270                          * read-write path.
1271                          */
1272                         resolve_lofs(zlogp, fsptr->zone_fs_special,
1273                             sizeof (fsptr->zone_fs_special));
1274                 }
1275         }
1276 
1277         /*
1278          * Run 'fsck -m' if there's a device to fsck.
1279          */
1280         if (fsptr->zone_fs_raw[0] != '\0' &&
1281             dofsck(zlogp, fsptr->zone_fs_type, fsptr->zone_fs_raw) != 0) {
1282                 return (-1);
1283         } else if (isregfile(fsptr->zone_fs_special) == 1 &&
1284             dofsck(zlogp, fsptr->zone_fs_type, fsptr->zone_fs_special) != 0) {
1285                 return (-1);
1286         }
1287 
1288         /*
1289          * Build up mount option string.
1290          */
1291         optstr[0] = '\0';
1292         if (fsptr->zone_fs_options != NULL) {
1293                 (void) strlcpy(optstr, fsptr->zone_fs_options->zone_fsopt_opt,
1294                     sizeof (optstr));
1295                 for (optptr = fsptr->zone_fs_options->zone_fsopt_next;
1296                     optptr != NULL; optptr = optptr->zone_fsopt_next) {
1297                         (void) strlcat(optstr, ",", sizeof (optstr));
1298                         (void) strlcat(optstr, optptr->zone_fsopt_opt,
1299                             sizeof (optstr));
1300                 }
1301         }
1302 
1303         if ((rv = domount(zlogp, fsptr->zone_fs_type, optstr,
1304             fsptr->zone_fs_special, path)) != 0)
1305                 return (rv);
1306