/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This file contains functions that allow applications to roll the log.
* It is intended for use by applications that open a raw device with the
* understanding that it contains a Unix File System.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <libintl.h>
#include "roll_log.h"
/*
* The following is the template string passed to mktemp(3C). This
* string is used as the name of a temporary mount point which is
* used to roll the log.
*/
#define RLM_RW 0
/*
* Structure definitions:
*/
typedef struct log_info {
} log_info_t;
/*
* Static function declarations:
*/
/*
* NAME
* rl_roll_log
*
* SYNOPSIS
* rl_roll_log(block_dev)
*
* DESCRIPTION
* Roll the log for the block device "block_dev".
*/
{
} else {
/*
* Device appears not to be mounted.
* We need to mount the device read only.
* This automatically causes the log to be rolled, then we can
* unmount the device again. To do the mount, we need to
* create a temporary directory, and then remove it when we
* are done.
*/
switch (rv) {
case RL_CORRUPT:
/* corrupt mnttab - the file sys really was mounted */
break;
case RL_SUCCESS:
if (rv == RL_SUCCESS) {
}
}
break;
}
}
return (rv);
}
/*
* Static function definitions:
*/
/*
* NAME
* cleanup
*
* SYNOPSIS
* cleanup(log_infop)
*
* DESCRIPTION
* Remove the temporary mount directroy and free the dynamically
* allocated memory that is pointed to by log_infop.
*/
static void
{
}
}
}
}
}
/*
* NAME
* is_mounted
*
* SYNOPSIS
* is_mounted(log_infop, dev)
*
* DESCRIPTION
* Determine if device dev is mounted, and return RL_TRUE if it is.
* As a side effect, li_blkname is set to point the the full path
* names of the block device. Memory for this path is dynamically
* allocated and must be freed by the caller.
*/
extern char *getfullblkname(char *);
static rl_result_t
{
/* Make sure that we have the full path name. */
/* Search mnttab to see if it device is mounted. */
return (rv);
/* Entry is UFS */
== 0) ||
break;
}
}
}
return (rv);
}
/*
* NAME
* make_mp
*
* SYNOPSIS
* make_mp(loginfop)
*
* DESCRIPTION
* Create a temporary directory to be used as a mount point. li_tmpmp
* will be set to the path of the mount point. li_tmpmp_parent is the
* parent directory of the mount point. The parent directory is
* created with restrictive permissions. Memory pointed to by
* li_tmpmp and li_tmpmp_parent should be freed by the caller.
*/
static rl_result_t
{
size_t i;
/*
* Note tmp_dir_list[] should all be directories in the
* original root file system.
*/
static const char *tmp_dir_list[] = {
"/tmp/",
"/",
};
sizeof (const char *);
int merr = 0;
/*
* Sequence of events:
* - Create a random name using mktemp(3C) (e.g., ".rlg.123456")
* - Cycle through tmp_dir_list to find a path where we can create
* a temporary parent directory (e.g., /tmp/.rlg.123456) with
* restrictive permissions. This prevents any non-root processes,
* such as a 'find', from wandering in where it doesn't belong.
* - Create the mount-point (/tmp/.rlg.123456/.rlg.123456).
*/
for (i = 0; i < list_len; i++) {
/* Make the directory containing the mount-point */
tmp_dir_list[i], dirname);
continue;
}
/* Now, make the mount-point */
continue;
}
/* Make sure that the strdup()s both succeeded */
rv = RL_SUCCESS;
}
break;
}
/* Get some help if we cannot make the directory. */
if (rv != RL_SUCCESS) {
/*
* If we get a read only filesystem failure (EROFS)
* to make a directory in "/", then we must be fsck'ing
* at boot with a incorrect mnttab.
*
* Just return RL_CORRUPT to indicate it really
* was mounted.
*/
return (RL_CORRUPT);
}
"Unable to create temporary "
"directory in any of the directories listed "
"below:\n"));
for (i = 0; i < list_len; i++) {
}
"Please correct this problem "
"and rerun the program.\n"));
}
return (rv);
}
/*
* NAME
* rlflush
*
* SYNOPSIS
* rlflush(log_infop)
*
* DESCRIPTION
* Open the mount point of the file system (li_mntpoint) to get a
* file descriptor. Issue the _FIOFFS ioctl to flush the file system
* and then close the device.
*/
static rl_result_t
{
return (RL_SYSERR);
}
}
return (rv);
}
/*
* NAME
* rlmount
*
* SYNOPSIS
* rlmount(log_infop, mntopt)
*
* DESCRIPTION
* Mount the device specified by li_blkname on li_tmpmp. mntopt specifies
* whether it's mounted RLM_RO or RLM_RW.
*/
static rl_result_t
{
char *optstr;
int optflg;
/*
* Use a minimal restrictive set of mount options. Make sure
* (Although "nosub" isn't a currently supported option on UFS,
* it would be a good one to have if it ever is implemented
* since submounts would prevent a umount.)
*/
switch (mntopt) {
case RLM_RO:
break;
case RLM_RW:
optflg = 0;
break;
default:
return (RL_FAIL);
}
}
return (rv);
}
/*
* NAME
* rlumount
*
* SYNOPSIS
* rlumount(log_infop)
*
* DESCRIPTION
* Unmounts the device specified by li_blkname, printing an
* error message on failure.
*/
static rl_result_t
{
"WARNING: rlumount(): Can't unmount %s\n"),
lip->li_blkname);
}
return (rv);
}
/*
* NAME
* rl_log_control
*
* SYNOPSIS
* rl_log_control(block_dev, request)
*
* DESCRIPTION
* The request parameter should be set to _FIOLOGENABLE or
* _FIOLOGDISABLE.
*/
{
int fd;
int logenabled = 0;
return (RL_FAIL);
/*
* Device is not mounted. Need to mount it rw to allow
* to create a temporary directory, and then remove it when
* we are done.
*/
return (RL_FAIL);
}
return (RL_FAIL);
}
}
if (alreadymounted == RL_TRUE)
else
perror("open");
goto out;
}
fl.nbytes_requested = 0;
fl.nbytes_actual = 0;
perror("ioctl");
goto out;
}
perror("ioctl");
goto out;
}
out:
if (alreadymounted != RL_TRUE)
return (rv);
}