blob: 8024bb2911ff332bd9fbe3d03a23d9da1a6647d2 [file] [log] [blame] [raw]
/*
* Copyright (C) 2000-2005 SWsoft. All rights reserved.
*
* This file may be distributed under the terms of the Q Public License
* as defined by Trolltech AS of Norway and appearing in the file
* LICENSE.QPL included in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mount.h>
#include "fs.h"
#include "util.h"
#include "logger.h"
#include "vzerror.h"
#include "script.h"
#include "quota.h"
int vps_is_run(vps_handler *h, envid_t veid);
/** Get VPS mount status.
*
* @param root VPS root.
* @return 1 - VPS mounted
* 0 - VPS unmounted.
* -1- error
*/
int vps_is_mounted(char *root)
{
return vz_fs_is_mounted(root);
}
/** Mount VPS.
*
* @param veid VPS id.
* @param fs file system parameters.
* @param dq disk quota parameters.
* @return 0 on success.
*/
int fsmount(envid_t veid, fs_param *fs, dq_param *dq)
{
int ret;
/* Create VE_ROOT mount point if not exist */
if (make_dir(fs->root, 1)) {
logger(0, 0, "Can't create mount point %s", fs->root);
return VZ_FS_MPOINTCREATE;
}
if ((ret = vps_quotaon(veid, fs->private, dq)))
return ret;
if ((ret = vz_mount(fs, 0)))
vps_quotaoff(veid, dq);
return ret;
}
static int real_umount(envid_t veid, char *root)
{
int i, ret, n;
n = 0;
for (i = 0; i < 2; i++) {
while (1) {
ret = umount2(root, MNT_DETACH);
if (ret < 0) {
if (n > 0 && errno == EINVAL)
ret = 0;
break;
}
n++;
}
if (ret == 0 || (ret < 0 && errno != EBUSY))
break;
sleep(1);
}
if (ret) {
logger(0, errno, "Can't umount: %s", root);
ret = VZ_FS_CANTUMOUNT;
}
return ret;
}
/** Unmount VPS.
*
* @param veid VPS id.
* @param root VPS root.
* @return 0 on success.
*/
int fsumount(envid_t veid, char *root)
{
int ret;
if (!(ret = real_umount(veid, root))) {
if (!quota_ctl(veid, QUOTA_STAT))
ret = quota_off(veid, 0);
}
return ret;
}
/** Mount VPS and run mount action script if exists.
*
* @param h VPS handler.
* @param veid VPS id.
* @param fs file system parameters.
* @param dq disk quota parameters.
* @param skip skip mount action scrips
* @return 0 on success.
*/
int vps_mount(vps_handler *h, envid_t veid, fs_param *fs, dq_param *dq,
skipFlags skip)
{
char buf[PATH_LEN];
int ret, i;
if (check_var(fs->root, "VE_ROOT is not set"))
return VZ_VE_ROOT_NOTSET;
if (check_var(fs->private, "VE_PRIVATE is not set"))
return VZ_VE_PRIVATE_NOTSET;
if (!stat_file(fs->private)) {
logger(0, 0, "VPS private area %s does not exist", fs->private);
return VZ_FS_NOPRVT;
}
if (vps_is_mounted(fs->root)) {
logger(0, 0, "VPS is already mounted");
return 0;
}
if ((ret = fsmount(veid, fs, dq)))
return ret;
/* Execute per VPS & global mount scripts */
if (!(skip & SKIP_ACTION_SCRIPT)) {
snprintf(buf, sizeof(buf), "%svps.%s", VPS_CONF_DIR,
MOUNT_PREFIX);
for (i = 0; i < 2; i++) {
if (run_pre_script(veid, buf)) {
logger(0, 0, "Error executing mount script %s",
buf);
fsumount(veid, fs->root);
return VZ_ACTIONSCRIPT_ERROR;
}
snprintf(buf, sizeof(buf), "%s%d.%s", VPS_CONF_DIR,
veid, MOUNT_PREFIX);
}
}
logger(0, 0, "VPS is mounted");
return 0;
}
/** Unmount VPS and run unmount action script if exists.
*
* @param h VPS handler.
* @param veid VPS id.
* @param root VPS root.
* @param skip skip unmount action scrips
* @return 0 on success.
*/
int vps_umount(vps_handler *h, envid_t veid, char *root, skipFlags skip)
{
char buf[PATH_LEN];
int ret, i;
if (!vps_is_mounted(root)) {
logger(0, 0, "VPS is not mounted");
return VZ_FS_NOT_MOUNTED;
}
if (vps_is_run(h, veid)) {
logger(0, 0, "VPS is running. Stop VPS first");
return 0;
}
if (!(skip & SKIP_ACTION_SCRIPT)) {
snprintf(buf, sizeof(buf), "%svps.%s", VPS_CONF_DIR,
UMOUNT_PREFIX);
for (i = 0; i < 2; i++) {
if (run_pre_script(veid, buf)) {
logger(0, 0, "Error executing umount script %s",
buf);
return VZ_ACTIONSCRIPT_ERROR;
}
snprintf(buf, sizeof(buf), "%s%d.%s", VPS_CONF_DIR,
veid, UMOUNT_PREFIX);
}
}
if (!(ret = fsumount(veid, root)))
logger(0, 0, "VPS is unmounted");
return 0;
}
int vps_set_fs(fs_param *g_fs, fs_param *fs)
{
if (fs->noatime != YES)
return 0;
if (check_var(g_fs->root, "VE_ROOT is not set"))
return VZ_VE_ROOT_NOTSET;
if (check_var(g_fs->private, "VE_PRIVATE is not set"))
return VZ_VE_PRIVATE_NOTSET;
if (!vps_is_mounted(g_fs->root)) {
logger(0, 0, "VPS is not mounted");
return VZ_FS_NOT_MOUNTED;
}
g_fs->noatime = fs->noatime;
return vz_mount(g_fs, 1);
}