Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

mntd_mount.c

00001 /***************************************************************************
00002  * CVSID: $Id: mntd_mount.c,v 1.19 2005/03/29 23:32:03 stefanb Exp $
00003  *
00004  * mntd_mount.c : Mount helper for MNT daemon
00005  *
00006  * Copyright (C) 2004 Stefan Bambach, <sbambach@gmx.net>
00007  *
00008  * Licensed under the GNU General Public License 2.0
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  **************************************************************************/
00025  
00026 #ifdef HAVE_CONFIG_H
00027 #  include <config.h>
00028 #endif
00029 
00030 #include <mntent.h>
00031 #include <stdlib.h>
00032 #include <glib.h>
00033 #include <errno.h>
00034 
00035 #include "mntd_mount.h"
00036 #include "errmanager.h"
00037 #include "main.h"
00038 #include "dbug_mem.h"
00039 
00040 
00041 extern int errno;
00042 
00043 
00058 int 
00059 mntd_mount_mount(const char *device, const char *mntpnt)
00060 {
00061     gchar *g_cmd = NULL;
00062     int res = 0;
00063     
00064     g_assert(device!=NULL);
00065     g_assert(mntpnt!=NULL);
00066     
00067     // try to mount
00068     if (mntd_mount_is_mounted(mntpnt) == 0) {
00069         g_cmd = g_strjoin(" ", MOUNT_BIN_PATH, "-o", "ro", device, mntpnt, NULL);
00070         if (g_cmd != NULL) {
00071             MSG_DEBUG("Mounting with '%s'", g_cmd);
00072             res = system(g_cmd);
00073             if (res == -1) {
00074                 MSG_ERR("Error mounting '%s' on '%s': %s", device, mntpnt, strerror(errno));
00075                 goto error;
00076             }
00077         } else {
00078             goto error;
00079         }
00080         
00081         // remounting, if needed
00082         MSG_DEBUG("trying to remount with user options from configfile ...");
00083         if (mntd_mount_is_mounted(mntpnt) == 1) {
00084             int r = -1;
00085             r = mntd_mount_remount_from_configfile(mntpnt);
00086             MSG_DEBUG("mntd_mount_remount_from_configfile('%s') returns %d", mntpnt, r);
00087         }
00088 
00089     } else {
00090         // return successful, if not mounted
00091         MSG_DEBUG("mount('%s') called, but it's already mounted -> ignoring", mntpnt);
00092     }
00093     
00094     goto cleanup;
00095     
00096 error:
00097     res = -1;
00098     
00099 cleanup:
00100     if (g_cmd != NULL) {
00101         g_free(g_cmd);
00102         g_cmd = NULL;
00103     }
00104     
00105     return res;
00106 }
00107 
00108 
00114 int 
00115 mntd_mount_umount(const char *mntpnt)
00116 {
00117     gchar *g_cmd = NULL;
00118     int res = 0;
00119     
00120     g_assert(mntpnt!=NULL);
00121     
00122     if (mntd_mount_is_mounted(mntpnt) == 1) {
00123         g_cmd = g_strjoin(" ", UMOUNT_BIN_PATH, "-f", "-l", mntpnt, NULL);
00124         if (g_cmd != NULL) {
00125             MSG_DEBUG("Unmounting with '%s'", g_cmd);
00126             res = system(g_cmd);
00127             if (res == -1) {
00128                 MSG_ERR("Error unmounting '%s': %s", mntpnt, strerror(errno));
00129                 goto error;
00130             }
00131         } else {
00132             goto error;
00133         }
00134     } else {
00135         // return successful, if not mounted
00136         MSG_DEBUG("unmount('%s') called, but it's not mounted -> ignoring", mntpnt);
00137     }
00138     
00139     goto cleanup;
00140     
00141 error:
00142     res = -1;
00143     
00144 cleanup:
00145     if (g_cmd != NULL) {
00146         g_free(g_cmd);
00147         g_cmd = NULL;
00148     }
00149     
00150     return res;
00151 }
00152 
00153 
00161 int 
00162 _mntd_mount_remount(const char *user_opts, const char *mntpnt)
00163 {
00164     gchar *g_joined = NULL;
00165     gchar *g_opts = NULL;
00166     gchar *g_cmd = NULL;
00167     int res = 0;
00168     
00169     g_assert(user_opts!=NULL);
00170     g_assert(mntpnt!=NULL);
00171 
00172     if (strlen(user_opts) > 0) {
00173         if (mntd_mount_is_mounted(mntpnt) == 1) {
00174             g_joined = g_strjoin(",", "remount", user_opts, NULL);
00175             if (g_joined != NULL) {
00176                 g_opts = g_shell_quote(g_joined);
00177                 if (g_opts != NULL) {
00178                     g_cmd = g_strjoin(" ", MOUNT_BIN_PATH, "-o", g_opts, mntpnt, NULL);
00179                     if (g_cmd != NULL) {
00180                         res = system(g_cmd);
00181                         if (res == -1) {
00182                             MSG_ERR("Error remounting '%s': %s", mntpnt, strerror(errno));
00183                             goto error;
00184                         }
00185                         MSG_DEBUG("Remounting with '%s' returns %d", g_cmd, res);
00186                     } else {
00187                         goto error;
00188                     }
00189                 } else {
00190                     goto error;
00191                 }
00192             } else {
00193                 goto error;
00194             }
00195         }
00196     }
00197     
00198     goto cleanup;
00199     
00200 error:
00201     res = -1;
00202     
00203 cleanup:
00204     if (g_cmd != NULL) {
00205         g_free(g_cmd);
00206         g_cmd = NULL;
00207     }
00208     if (g_opts != NULL) {
00209         g_free(g_opts);
00210         g_opts = NULL;
00211     }
00212     if (g_joined != NULL) {
00213         g_free(g_joined);
00214         g_joined = NULL;
00215     }
00216     
00217     return res;
00218 }
00219 
00220 
00226 int 
00227 mntd_mount_remount_rd(const char *mntpnt)
00228 {
00229     int res = -1;
00230     
00231     g_assert(mntpnt!=NULL);
00232 
00233     if (mntd_mount_is_mounted(mntpnt) == 1) {
00234         res = _mntd_mount_remount("ro", mntpnt);
00235     }
00236     
00237     return res;
00238 }
00239 
00240 
00246 int 
00247 mntd_mount_remount_rw(const char *mntpnt)
00248 {
00249     int res = -1;
00250     
00251     g_assert(mntpnt!=NULL);
00252 
00253     if (mntd_mount_is_mounted(mntpnt) == 1) {
00254         res = _mntd_mount_remount("rw", mntpnt);
00255     }
00256     
00257     return res;
00258 }
00259 
00260 
00266 int 
00267 mntd_mount_remount_from_configfile(const char *mntpnt)
00268 {
00269     char *fsname = NULL;
00270     char *fsoptions = NULL;
00271     gchar *o = NULL;
00272     int res = -1;
00273     
00274     g_assert(mntpnt!=NULL);
00275 
00276     if (mntd_mount_is_mounted(mntpnt) == 1) {
00277         fsname = mntd_mount_getfsname(mntpnt);
00278         if (fsname != NULL) {
00279             fsoptions = mntd_mount_getoptions(mntpnt);
00280             if (fsoptions != NULL) {
00281                 o = mntd_mount_normalize_options(g_hash_table_lookup(pmd->configdata->filesystems, 
00282                     fsname));
00283                 // no remount, if nothing configured
00284                 if (o!=NULL) {
00285                     // only try to remount, if options are different
00286                     if (strcmp(fsoptions, o) != 0) {
00287                         // remount with options from configfile
00288                         res = _mntd_mount_remount(o, mntpnt);
00289                         if (res == -1) {
00290                             MSG_WARNING("Remount '%s' with options from config '%s' failed -> falling back to standard options", 
00291                                 mntpnt, o);
00292                             res = _mntd_mount_remount(fsoptions, mntpnt);
00293                         }
00294                     } else {
00295                         MSG_DEBUG("mtab options are identical to configfile -> nothing to be done.");
00296                         res = 0;
00297                     }
00298                     g_free(o);
00299                 } else {
00300                     MSG_DEBUG("No options for filesystem '%s' in configfile found.", 
00301                         fsname);
00302                     res = 0;
00303                 }
00304                 g_free(fsoptions);
00305             } else {
00306                 MSG_ERR("Couldn't get fsoptions from mtab for '%s'", mntpnt);
00307             }
00308             free(fsname);
00309         } else {
00310             MSG_ERR("Couldn't get fsname from mtab for '%s'", mntpnt);
00311         }
00312     } else {
00313         MSG_ERR("mntd_mount_remount_from_configfile('%s') called, but it's not mounted", mntpnt);
00314     }
00315     
00316     return res;
00317 }
00318 
00319 
00324 FILE *
00325 mntd_mount_open_mtab(void)
00326 {
00327     FILE *mtab = NULL;
00328     
00329     // try to open mount table
00330     mtab = setmntent("/etc/mtab", "r");
00331     if (mtab==NULL) {
00332         mtab = setmntent("/proc/mounts", "r");
00333         if (mtab==NULL) {
00334             return NULL;
00335         }
00336     }
00337     
00338     return mtab;
00339 }
00340     
00341 
00347 int 
00348 mntd_mount_is_mounted(const char *path)
00349 {
00350     int res = 0;
00351     FILE *mtab = NULL;
00352     struct mntent *me = NULL;
00353     
00354     // try to open mount table
00355     mtab = mntd_mount_open_mtab();
00356     if (mtab==NULL) {
00357         return 0;
00358     }
00359     
00360     // check entries
00361     while ((me = getmntent(mtab)) != 0) {
00362         if ((strcmp(path, me->mnt_dir) == 0) || 
00363              (strcmp(path, me->mnt_fsname) == 0)) {
00364             res = 1;
00365             break;
00366         }
00367     }
00368     endmntent(mtab);
00369     
00370     return res;
00371 }
00372 
00373 
00379 struct mntent * 
00380 mntd_mount_getmntent(const char *path)
00381 {
00382     struct mntent *res = NULL;
00383     FILE *mtab = NULL;
00384     struct mntent *me = NULL;
00385     
00386     // try to open mount table
00387     mtab = mntd_mount_open_mtab();
00388     if (mtab==NULL) {
00389         return NULL;
00390     }
00391     
00392     // check entries
00393     while ((me = getmntent(mtab)) != 0) {
00394         if ((strcmp(path, me->mnt_dir) == 0) || 
00395              (strcmp(path, me->mnt_fsname) == 0)) {
00396             res = (struct mntent *) malloc(sizeof(struct mntent));
00397             if (res != NULL) {
00398                 res->mnt_fsname = strdup(me->mnt_fsname);
00399                 res->mnt_dir = strdup(me->mnt_dir);
00400                 res->mnt_type = strdup(me->mnt_type);
00401                 res->mnt_opts = strdup(me->mnt_opts);
00402                 res->mnt_freq = me->mnt_freq;
00403                 res->mnt_passno = me->mnt_passno;
00404             }
00405             break;
00406         }
00407     }
00408     endmntent(mtab);
00409     
00410     return res;
00411 }
00412 
00413 
00419 char *
00420 mntd_mount_getfsname(const char *path)
00421 {
00422     char *res = NULL;
00423     FILE *mtab = NULL;
00424     struct mntent *me = NULL;
00425     
00426     // try to open mount table
00427     mtab = mntd_mount_open_mtab();
00428     if (mtab==NULL) {
00429         return NULL;
00430     }
00431     
00432     // check entries
00433     while ((me = getmntent(mtab)) != 0) {
00434         if ((strcmp(path, me->mnt_dir) == 0) || 
00435              (strcmp(path, me->mnt_fsname) == 0)) {
00436             res = strdup(me->mnt_type);
00437             break;
00438         }
00439     }
00440     endmntent(mtab);
00441     
00442     return res;
00443 }
00444 
00445 
00451 gchar *
00452 mntd_mount_getoptions(const char *path)
00453 {
00454     char *res = NULL;
00455     FILE *mtab = NULL;
00456     struct mntent *me = NULL;
00457     
00458     // try to open mount table
00459     mtab = mntd_mount_open_mtab();
00460     if (mtab==NULL) {
00461         return NULL;
00462     }
00463     
00464     // check entries
00465     while ((me = getmntent(mtab)) != 0) {
00466         if ((strcmp(path, me->mnt_dir) == 0) || 
00467              (strcmp(path, me->mnt_fsname) == 0)) {
00468             res = mntd_mount_normalize_options(me->mnt_opts);
00469             break;
00470         }
00471     }
00472     endmntent(mtab);
00473     
00474     return res;
00475 }
00476 
00477 
00483 gchar *
00484 mntd_mount_normalize_options(const char *options)
00485 {
00486     gchar **ov = NULL;
00487     gchar **oe = NULL;
00488     gchar *o = NULL;
00489     char *res = NULL;
00490     
00491     if (options != NULL) {
00492         o = g_strdup(options);
00493         if (o != NULL) {
00494             ov = g_strsplit(g_strstrip(o), ",", 0);
00495             if (ov != NULL) {
00496                 oe = ov;
00497                 while (*oe != NULL) {
00498                     *oe = g_strstrip(*oe);
00499                     oe++;
00500                 }
00501                 res = (char *) g_strjoinv(",", ov);
00502                 g_strfreev(ov);
00503             }
00504             g_free(o);
00505         }
00506     }
00507 
00508     return res;
00509 }
00510 
00511 

Generated on Wed Mar 30 13:43:26 2005 for Mntd by  doxygen 1.3.9.1