libgrub_fs.c revision 8c7cfd880e3f539ab3041a3168beec560e4ff5d9
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file contains all the functions that manipualte the file
* system where the GRUB menu resides.
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <libfstyp.h>
#include "libgrub_impl.h"
static int
{
const char *pos;
}
/*
* Returns zero if path contains ufs
*/
static int
{
const char *id;
}
return (ret);
}
static int
get_sol_prtnum(const char *physpath)
{
int i, fd;
char *pos;
char boot_sect[512];
char rdev[MAXNAMELEN];
return (PRTNUM_INVALID);
return (PRTNUM_INVALID);
/* parse fdisk table */
for (i = 0; i < FD_NUMPART; ++i) {
return (i);
}
return (PRTNUM_INVALID);
}
/*
* Get physpath, topfs and bootfs for ZFS root dataset.
* Return 0 on success, non-zero (not errno) on failure.
*/
static int
{
int ret;
const char *name;
return (-1);
sizeof (root->gr_physpath))) == 0 &&
}
return (ret);
}
/*
* On entry physpath parameter supposed to contain:
* <disk_physpath>[<space><disk_physpath>]*.
* Retireives first <disk_physpath> that matches both partition and slice.
* If any partition and slice is acceptable, first <disk_physpath> is returned.
*/
static int
{
int ret;
return (0);
}
return (errno);
break;
}
}
if (ret)
return (ret);
}
static int
{
char path[MAXPATHLEN];
do {
break;
/*
* if top zfs dataset is not mounted, mount it now
*/
GRBM_ZFS_TOPFS, MNTTYPE_ZFS) != 0)
break;
}
/* check that bootsign exists and it is a regular file */
barg->gb_bootsign);
break;
barg->gb_walkret = 0;
/* LINTED: E_CONSTANT_CONDITION */
} while (0);
/* return non-zero to terminate the walk */
return (barg->gb_walkret == 0);
}
static int
{
const char *path;
return (DI_WALK_TERMINATE);
}
static int
{
int ret;
char path[MAXPATHLEN];
return (errno);
/*
* if disk is not mounted, mount it now
*/
MNTTYPE_UFS) != 0) {
if ((ret =
MNTTYPE_UFS)) != 0)
return (ret);
}
barg->gb_walkret = 0;
}
return (barg->gb_walkret);
}
static int
{
return (DI_WALK_CONTINUE);
return (DI_WALK_CONTINUE);
if (!IS_PRTNUM_VALID(prtnum))
return (DI_WALK_CONTINUE);
/*
* check only specified partition, slice
*/
return (DI_WALK_CONTINUE);
return (DI_WALK_TERMINATE);
}
/*
* Walk through all slices in found solaris partition
*/
continue;
continue;
if (ufs_bootsign_check(barg) == 0)
return (DI_WALK_TERMINATE);
}
return (DI_WALK_CONTINUE);
}
/*
* Differs from what GRUB is doing: GRUB searchs through all disks seen by bios
* for bootsign, if bootsign is found on ufs slice GRUB sets it as a root,
* if on zfs, then GRUB uses zfs slice as root only if bootsign wasn't found
* on other slices.
* That function first searches through all top datasets of active zpools,
* then if bootsign still not found walks through all disks and tries to
* find ufs slice with the bootsign.
*/
int
{
/* try to find bootsign over zfs pools */
/* try ufs now */
return (errno);
return (barg->gb_walkret);
}
/*
* Get current root file system.
* Return 0 on success, errno code on failure.
*/
int
{
int rc = 0;
char buf[MAXNAMELEN] = {0};
return (errno);
/*
* getmntany returns non-zero for failure, and sets errno
*/
if (rc != 0)
if (rc != 0)
return (rc);
return (EG_CURROOT);
NULL)
return (EG_OPENZFS);
/*
* get_zfs_root returns non-zero on failure, not errno.
*/
rc = EG_CURROOT;
else
/*
* For mirrored root physpath would contain the list of
* all bootable devices, pick up the first one.
*/
} else {
rc = EG_UNKNOWNFS;
}
return (rc);
}
{
return (fsd);
}
/*
* Gets file systems mount point if any.
* Return 0 if filesystem is mounted, errno on failure.
*/
int
{
int rc;
fsd->gfs_mountp[0] = 0;
return (errno);
sizeof (fsd->gfs_mountp));
else
rc = EG_GETMNTTAB;
return (rc);
}
static const char tmp_mountp[] = "/tmp/.libgrubmgmt.%s.XXXXXX";
/*
* Mount file system at tmp_mountp.
* Return 0 on success, errno on failure.
*/
int
{
const char *pos;
int dtsz = 0;
int rc = 0;
fsd->gfs_mountp[0] = 0;
return (EG_UNKNOWNFS);
}
/* construct name for temporary mount point */
tmp_mountp, pos);
/*
* mount failed, collect errno and remove temp dir
*/
}
} else {
}
if (rc != 0)
fsd->gfs_mountp[0] = 0;
/*
* Note that valid values for gfs_is_tmp_mounted are 0,1.
* Any other value indicates that something bad happened.
* Probably grub_fsd_umount_tmp() wasn't called or didn't
* work as expected.
*/
return (rc);
}
/*
* Unmount file system at tmp_mountp.
*/
void
{
return;
if (fsd->gfs_is_tmp_mounted) {
if (fsd->gfs_mountp[0] != 0) {
fsd->gfs_mountp[0] = 0;
}
fsd->gfs_is_tmp_mounted = 0;
}
}