00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
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
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
00284 if (o!=NULL) {
00285
00286 if (strcmp(fsoptions, o) != 0) {
00287
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
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
00355 mtab = mntd_mount_open_mtab();
00356 if (mtab==NULL) {
00357 return 0;
00358 }
00359
00360
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
00387 mtab = mntd_mount_open_mtab();
00388 if (mtab==NULL) {
00389 return NULL;
00390 }
00391
00392
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
00427 mtab = mntd_mount_open_mtab();
00428 if (mtab==NULL) {
00429 return NULL;
00430 }
00431
00432
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
00459 mtab = mntd_mount_open_mtab();
00460 if (mtab==NULL) {
00461 return NULL;
00462 }
00463
00464
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