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 <stdlib.h>
00031 #include <glib.h>
00032 #include <expat.h>
00033
00034 #include "file.h"
00035 #include "mntd_volume_config.h"
00036 #include "mntd_volume_manager.h"
00037 #include "errmanager.h"
00038 #include "dbug_mem.h"
00039
00040
00050 #define MAX_DEPTH 32
00051
00053 #define CDATA_BUF_SIZE 1024
00054
00056 #define MAX_KEY_SIZE 128
00057
00059 enum
00060 {
00062 CURELEM_UNKNOWN = -1,
00063
00065 CURELEM_MNTD = 0,
00066
00068 CURELEM_MOUNTPATH = 1,
00069
00071 CURELEM_USER = 2,
00072
00074 CURELEM_GROUP = 3,
00075
00077 CURELEM_WDIR = 4,
00078
00080 CURELEM_PIDFILE = 5,
00081
00083 CURELEM_FILESYSTEMS = 6,
00084
00086 CURELEM_FILESYSTEM = 7,
00087
00089 CURELEM_DBUS_RECONNECT = 8,
00090
00092 CURELEM_LOGLEVEL = 9,
00093
00095 CURELEM_UMOUNT_ON_EXIT = 10,
00096
00098 CURELEM_MOUNTPREFIX = 11,
00099
00100 };
00101
00102
00103
00106 typedef struct
00107 {
00109 ConfigData *c;
00110
00112 XML_Parser parser;
00113
00115 char *config;
00116
00118 char cdata_buf[CDATA_BUF_SIZE];
00119
00121 int cdata_buf_len;
00122
00124 int depth;
00125
00127 int curelem;
00128
00130 int curelem_stack[MAX_DEPTH];
00131
00133 int aborted;
00134
00135 } ParsingContext;
00136
00137
00138
00139 void mntd_volume_config_parsing_abort(ParsingContext* pc);
00140 void mntd_volume_config_start(ParsingContext *pc, const char *el, const char **attr);
00141 void mntd_volume_config_end(ParsingContext *pc, const char* el);
00142 void mntd_volume_config_cdata(ParsingContext *pc, const char* s, int len);
00143
00144
00145
00150 void
00151 mntd_volume_config_parsing_abort(ParsingContext* pc)
00152 {
00153 g_assert(pc!=NULL);
00154
00155
00156 MSG_ERR("Aborting parsing of document");
00157 pc->aborted = TRUE;
00158 }
00159
00160
00161
00168 void
00169 mntd_volume_config_start(ParsingContext *pc, const char *el, const char **attr)
00170 {
00171 int i = 0;
00172
00173 g_assert(pc!=NULL);
00174 g_assert(el!=NULL);
00175 g_assert(attr!=NULL);
00176
00177 MSG_DEBUG("start: %s", el);
00178
00179 for (i=0; attr[i]; i+=2) {
00180 MSG_DEBUG(" %s='%s'", attr[i], attr[i+1]);
00181 }
00182
00183
00184 if(pc->aborted) {
00185 return;
00186 }
00187
00188
00189 pc->cdata_buf_len = 0;
00190
00191 if (strcmp(el, "mntd") == 0) {
00192 if( pc->curelem!=CURELEM_UNKNOWN ) {
00193 MSG_ERR("%s:%d:%d: Element <mntd> must be a top-level "
00194 "element",
00195 pc->config,
00196 XML_GetCurrentLineNumber(pc->parser),
00197 XML_GetCurrentColumnNumber(pc->parser));
00198 mntd_volume_config_parsing_abort(pc);
00199 }
00200 pc->curelem = CURELEM_MNTD;
00201
00202 } else if (strcmp(el, "mountpath") == 0) {
00203 if( pc->curelem!=CURELEM_MNTD ) {
00204 MSG_ERR("%s:%d:%d: Element <mountpath> can only be inside <mntd>",
00205 pc->config,
00206 XML_GetCurrentLineNumber(pc->parser),
00207 XML_GetCurrentColumnNumber(pc->parser));
00208 mntd_volume_config_parsing_abort(pc);
00209 }
00210 pc->curelem = CURELEM_MOUNTPATH;
00211
00212 } else if (strcmp(el, "mountprefix") == 0) {
00213 if( pc->curelem!=CURELEM_MNTD ) {
00214 MSG_ERR("%s:%d:%d: Element <mountprefix> can only be inside <mntd>",
00215 pc->config,
00216 XML_GetCurrentLineNumber(pc->parser),
00217 XML_GetCurrentColumnNumber(pc->parser));
00218 mntd_volume_config_parsing_abort(pc);
00219 }
00220 pc->curelem = CURELEM_MOUNTPREFIX;
00221
00222 } else if (strcmp(el, "user") == 0) {
00223 if( pc->curelem!=CURELEM_MNTD ) {
00224 MSG_ERR("%s:%d:%d: Element <user> can only be inside <mntd>",
00225 pc->config,
00226 XML_GetCurrentLineNumber(pc->parser),
00227 XML_GetCurrentColumnNumber(pc->parser));
00228 mntd_volume_config_parsing_abort(pc);
00229 }
00230 pc->curelem = CURELEM_USER;
00231
00232 } else if (strcmp(el, "group") == 0) {
00233 if( pc->curelem!=CURELEM_MNTD ) {
00234 MSG_ERR("%s:%d:%d: Element <group> can only be inside <mntd>",
00235 pc->config,
00236 XML_GetCurrentLineNumber(pc->parser),
00237 XML_GetCurrentColumnNumber(pc->parser));
00238 mntd_volume_config_parsing_abort(pc);
00239 }
00240 pc->curelem = CURELEM_GROUP;
00241
00242 } else if (strcmp(el, "wdir") == 0) {
00243 if( pc->curelem!=CURELEM_MNTD ) {
00244 MSG_ERR("%s:%d:%d: Element <wdir> can only be inside <mntd>",
00245 pc->config,
00246 XML_GetCurrentLineNumber(pc->parser),
00247 XML_GetCurrentColumnNumber(pc->parser));
00248 mntd_volume_config_parsing_abort(pc);
00249 }
00250 pc->curelem = CURELEM_WDIR;
00251
00252 } else if (strcmp(el, "pidfile") == 0) {
00253 if( pc->curelem!=CURELEM_MNTD ) {
00254 MSG_ERR("%s:%d:%d: Element <pidfile> can only be inside <mntd>",
00255 pc->config,
00256 XML_GetCurrentLineNumber(pc->parser),
00257 XML_GetCurrentColumnNumber(pc->parser));
00258 mntd_volume_config_parsing_abort(pc);
00259 }
00260 pc->curelem = CURELEM_PIDFILE;
00261
00262 } else if (strcmp(el, "filesystems") == 0) {
00263 if( pc->curelem!=CURELEM_MNTD ) {
00264 MSG_ERR("%s:%d:%d: Element <filesystems> can only be inside <mntd>",
00265 pc->config,
00266 XML_GetCurrentLineNumber(pc->parser),
00267 XML_GetCurrentColumnNumber(pc->parser));
00268 mntd_volume_config_parsing_abort(pc);
00269 }
00270 pc->curelem = CURELEM_FILESYSTEMS;
00271
00272 } else if (strcmp(el, "filesystem") == 0) {
00273 if( pc->curelem!=CURELEM_FILESYSTEMS ) {
00274 MSG_ERR("%s:%d:%d: Element <filesystem> can only be inside <filesystems>",
00275 pc->config,
00276 XML_GetCurrentLineNumber(pc->parser),
00277 XML_GetCurrentColumnNumber(pc->parser));
00278 mntd_volume_config_parsing_abort(pc);
00279 }
00280 gchar *fsname = NULL;
00281 gchar *fsoptions = NULL;
00282 for (i=0; attr[i]; i+=2) {
00283 if (strcmp(attr[i], "name") == 0) {
00284 fsname = (gchar *) attr[i+1];
00285 } else if (strcmp(attr[i], "options") == 0) {
00286 fsoptions = (gchar *) attr[i+1];
00287 } else {
00288 MSG_INF("Unknown attribute '%s' for element '%s'.", attr[i], el);
00289 }
00290 }
00291 if (pc->c != NULL) {
00292 g_hash_table_insert(pc->c->filesystems, g_strdup(fsname), g_strdup(fsoptions));
00293 }
00294 pc->curelem = CURELEM_FILESYSTEM;
00295
00296 } else if (strcmp(el, "dbus_reconnect") == 0) {
00297 if( pc->curelem!=CURELEM_MNTD ) {
00298 MSG_ERR("%s:%d:%d: Element <dbus_reconnect> can only be inside <mntd>",
00299 pc->config,
00300 XML_GetCurrentLineNumber(pc->parser),
00301 XML_GetCurrentColumnNumber(pc->parser));
00302 mntd_volume_config_parsing_abort(pc);
00303 }
00304 pc->c->sleep_millis = SLEEP_MILLIS_DEFAULT;
00305 char *str_sleep_millis = NULL;
00306 for (i=0; attr[i]; i+=2) {
00307 if (strcmp(attr[i], "sleep_millis") == 0) {
00308 str_sleep_millis = (char *) attr[i+1];
00309 } else {
00310 MSG_INF("Unknown attribute '%s' for element '%s'.", attr[i], el);
00311 }
00312 }
00313 if (str_sleep_millis != NULL) {
00314 char *endptr = NULL;
00315 char *nptr = str_sleep_millis;
00316 int value = strtol(nptr, &endptr, 0);
00317 if (((value == 0) && (nptr == endptr)) || (value < 0)) {
00318 MSG_WARNING("Invalid data for attribute 'sleep_millis' in <dbus_reconnect> (only numbers >= 0 allowed) -> using %d", SLEEP_MILLIS_DEFAULT);
00319 } else {
00320 pc->c->sleep_millis = value;
00321 }
00322 } else {
00323 MSG_INF("Attribute 'sleep_millis' in <dbus_reconnect> not specified -> using %d", SLEEP_MILLIS_DEFAULT);
00324 }
00325 pc->curelem = CURELEM_DBUS_RECONNECT;
00326
00327 } else if (strcmp(el, "loglevel") == 0) {
00328 if( pc->curelem!=CURELEM_MNTD ) {
00329 MSG_ERR("%s:%d:%d: Element <loglevel> can only be inside <mntd>",
00330 pc->config,
00331 XML_GetCurrentLineNumber(pc->parser),
00332 XML_GetCurrentColumnNumber(pc->parser));
00333 mntd_volume_config_parsing_abort(pc);
00334 }
00335 pc->curelem = CURELEM_LOGLEVEL;
00336
00337 } else if (strcmp(el, "umount_on_exit") == 0) {
00338 if( pc->curelem!=CURELEM_MNTD ) {
00339 MSG_ERR("%s:%d:%d: Element <umount_on_exit> can only be inside <mntd>",
00340 pc->config,
00341 XML_GetCurrentLineNumber(pc->parser),
00342 XML_GetCurrentColumnNumber(pc->parser));
00343 mntd_volume_config_parsing_abort(pc);
00344 }
00345 pc->curelem = CURELEM_UMOUNT_ON_EXIT;
00346
00347 } else {
00348 MSG_ERR("%s:%d:%d: Unknown element <%s>",
00349 pc->config,
00350 XML_GetCurrentLineNumber(pc->parser),
00351 XML_GetCurrentColumnNumber(pc->parser), el);
00352 mntd_volume_config_parsing_abort(pc);
00353 }
00354
00355
00356 g_assert((pc->depth)<MAX_DEPTH);
00357
00358
00359 pc->depth++;
00360
00361
00362 pc->curelem_stack[pc->depth] = pc->curelem;
00363
00364 return;
00365 }
00366
00367
00368
00374 void
00375 mntd_volume_config_end(ParsingContext *pc, const char* el)
00376 {
00377 g_assert(pc!=NULL);
00378 g_assert(el!=NULL);
00379
00380 MSG_DEBUG("end: %s", el);
00381
00382
00383 if (pc->aborted) {
00384 return;
00385 }
00386
00387
00388 pc->cdata_buf[pc->cdata_buf_len]='\0';
00389
00390
00391 if (pc->curelem==CURELEM_MOUNTPATH) {
00392 MSG_DEBUG("content for mountpath='%s'", pc->cdata_buf);
00393 pc->c->mountpath = strdup(pc->cdata_buf);
00394
00395 } else if (pc->curelem==CURELEM_MOUNTPREFIX) {
00396 MSG_DEBUG("content for mountprefix='%s'", pc->cdata_buf);
00397 pc->c->mountprefix = strdup(pc->cdata_buf);
00398
00399 } else if (pc->curelem==CURELEM_USER) {
00400 MSG_DEBUG("content for user='%s'", pc->cdata_buf);
00401 pc->c->user = strdup(pc->cdata_buf);
00402
00403 } else if (pc->curelem==CURELEM_GROUP) {
00404 MSG_DEBUG("content for group='%s'", pc->cdata_buf);
00405 pc->c->group = strdup(pc->cdata_buf);
00406
00407 } else if (pc->curelem==CURELEM_WDIR) {
00408 MSG_DEBUG("content for wdir='%s'", pc->cdata_buf);
00409 pc->c->wdir = strdup(pc->cdata_buf);
00410
00411 } else if (pc->curelem==CURELEM_PIDFILE) {
00412 MSG_DEBUG("content for pidfile='%s'", pc->cdata_buf);
00413 MSG_DEBUG("Ignoring deprecated <pidfile>%s</pidfile> -> use commandline parameter instead", pc->cdata_buf);
00414
00415 } else if (pc->curelem==CURELEM_DBUS_RECONNECT) {
00416 MSG_DEBUG("content for dbus_reconnect='%s'", pc->cdata_buf);
00417 char *endptr = NULL;
00418 char *nptr = pc->cdata_buf;
00419 int value = strtol(nptr, &endptr, 0);
00420 if ((value == 0) && (nptr == endptr)) {
00421 MSG_WARNING("Invalid data for <dbus_reconnect> in configfile (only numbers allowed) -> using -1");
00422 pc->c->dbus_reconnect = -1;
00423 } else {
00424 pc->c->dbus_reconnect = value;
00425 }
00426
00427 } else if (pc->curelem==CURELEM_LOGLEVEL) {
00428 MSG_DEBUG("content for loglevel='%s'", pc->cdata_buf);
00429 char *endptr = NULL;
00430 char *nptr = pc->cdata_buf;
00431 int value = strtol(nptr, &endptr, 0);
00432 if ((value == 0) && (nptr == endptr)) {
00433 MSG_WARNING("Invalid data for <dbus_reconnect> in configfile (only numbers allowed) -> using %d",
00434 LOG_NOTICE);
00435 pc->c->loglevel = LOG_NOTICE;
00436 } else {
00437 if (value < LOG_EMERG) {
00438 MSG_WARNING("option for loglevel out of range (%d <= loglevel <= %d) -> using %d",
00439 LOG_EMERG, LOG_DEBUG, LOG_EMERG);
00440 pc->c->loglevel = LOG_EMERG;
00441 } else if (value > LOG_DEBUG) {
00442 MSG_WARNING("option for loglevel out of range (%d <= loglevel <= %d) -> using %d",
00443 LOG_EMERG, LOG_DEBUG, LOG_DEBUG);
00444 pc->c->loglevel = LOG_DEBUG;
00445 } else {
00446 pc->c->loglevel = value;
00447 }
00448 }
00449
00450 } else if (pc->curelem==CURELEM_UMOUNT_ON_EXIT) {
00451 MSG_DEBUG("content for umount_on_exit='%s'", pc->cdata_buf);
00452 if (strcasecmp(pc->cdata_buf, "true") == 0) {
00453 pc->c->umount_on_exit = UMOUNT_ON_EXIT_TRUE;
00454 } else if (strcasecmp(pc->cdata_buf, "false") == 0) {
00455 pc->c->umount_on_exit = UMOUNT_ON_EXIT_FALSE;
00456 } else if (strcasecmp(pc->cdata_buf, "readonly") == 0) {
00457 pc->c->umount_on_exit = UMOUNT_ON_EXIT_READONLY;
00458 } else {
00459 MSG_WARNING("Invalid data for <umount_on_exit> in configfile (only true|false|readonly allowed) -> using true");
00460 pc->c->umount_on_exit = UMOUNT_ON_EXIT_TRUE;
00461 }
00462
00463 }
00464
00465
00466 pc->cdata_buf_len = 0;
00467
00468
00469 pc->depth--;
00470
00471
00472 pc->curelem = pc->curelem_stack[pc->depth];
00473
00474 return;
00475 }
00476
00477
00478
00485 void
00486 mntd_volume_config_cdata(ParsingContext *pc, const char* s, int len)
00487 {
00488 int bytes_left;
00489 int bytes_to_copy;
00490
00491 g_assert(pc!=NULL);
00492 g_assert(s!=NULL);
00493
00494
00495 if (pc->aborted) {
00496 return;
00497 }
00498
00499 bytes_left = CDATA_BUF_SIZE - pc->cdata_buf_len;
00500 if (len>bytes_left) {
00501 MSG_ERR("CDATA in element larger than %d", CDATA_BUF_SIZE);
00502 }
00503
00504 bytes_to_copy = len;
00505 if (bytes_to_copy>bytes_left) {
00506 bytes_to_copy = bytes_left;
00507 }
00508
00509 if (bytes_to_copy>0) {
00510 memcpy(pc->cdata_buf + pc->cdata_buf_len, s, bytes_to_copy);
00511 }
00512
00513 pc->cdata_buf_len += bytes_to_copy;
00514
00515 return;
00516 }
00517
00518
00519
00520 #ifdef DEBUG
00521
00530 void print_hm_entry(gpointer key, gpointer value, gpointer user_data);
00531 void print_hm_entry(gpointer key, gpointer value, gpointer user_data)
00532 {
00533 MSG_INF(" %s='%s'", key, value);
00534 }
00535 #endif
00536
00537
00538
00545 ConfigData *
00546 mntd_volume_config_parse(char *config, char *pidfile)
00547 {
00548 char *data = NULL;
00549 XML_Parser parser = NULL;
00550 int size = 0;
00551 ParsingContext *parsing_context = NULL;
00552 ConfigData *configdata = NULL;
00553 char *cwd = NULL;
00554 char *absfilepath = NULL;
00555
00556 g_assert(config!=NULL);
00557 g_assert(pidfile!=NULL);
00558
00559 configdata = (ConfigData *) malloc(sizeof(ConfigData));
00560 if (configdata==NULL) {
00561 MSG_EMERG("No memory for storing ConfigData");
00562 goto error;
00563 }
00564
00565
00566 MSG_INF("Loading configuration from '%s'.", config);
00567 if(!sb_file_is_file(config)) {
00568 MSG_EMERG("Couldn't read config file from '%s'", config);
00569 goto error;
00570 }
00571
00572 if((size = sb_file_get_size(config)) == -1 ) {
00573 MSG_EMERG("Couldn't get config file size from '%s'", config);
00574 goto error;
00575 }
00576
00577
00578 data = sb_file_read(config);
00579 if (data == NULL) {
00580 MSG_EMERG("Couldn't read config file from '%s'", config);
00581 goto error;
00582 }
00583
00584
00585 parser = XML_ParserCreate(NULL);
00586
00587
00588 parsing_context = (ParsingContext*) malloc(sizeof(ParsingContext));
00589 if (parsing_context == NULL) {
00590 MSG_EMERG("Out of memory.");
00591 goto error;
00592 }
00593 parsing_context->depth = 0;
00594 parsing_context->cdata_buf_len = 0;
00595 memset(parsing_context->cdata_buf, 0, sizeof(parsing_context->cdata_buf));
00596 parsing_context->curelem = CURELEM_UNKNOWN;
00597 parsing_context->aborted = FALSE;
00598 parsing_context->parser = parser;
00599 parsing_context->config = config;
00600 parsing_context->c = configdata;
00601
00602
00603 memset(configdata, 0, sizeof(ConfigData));
00604
00605
00606 configdata->filesystems = g_hash_table_new_full(g_str_hash, g_str_equal,
00607 g_free, g_free);
00608
00609 configdata->pidfile = strdup(pidfile);
00610
00611
00612 if (g_path_is_absolute(config)) {
00613 configdata->absfilepath = strdup(config);
00614 } else {
00615 cwd = g_get_current_dir();
00616 if (cwd != NULL) {
00617 absfilepath = g_build_path(G_DIR_SEPARATOR_S, cwd, config, NULL);
00618 if (absfilepath != NULL) {
00619 char *path = strdup(absfilepath);
00620 if (path != NULL) {
00621 configdata->absfilepath = path;
00622 } else {
00623 MSG_ERR("Out of memory.");
00624 goto error;
00625 }
00626 } else {
00627 MSG_ERR("Out of memory.");
00628 goto error;
00629 }
00630 } else {
00631 MSG_ERR("Out of memory.");
00632 goto error;
00633 }
00634 }
00635
00636
00637
00638 XML_SetElementHandler(parser,
00639 (XML_StartElementHandler) mntd_volume_config_start,
00640 (XML_EndElementHandler) mntd_volume_config_end);
00641 XML_SetCharacterDataHandler(parser,
00642 (XML_CharacterDataHandler) mntd_volume_config_cdata);
00643 XML_SetUserData(parser, parsing_context);
00644 if (XML_Parse(parser, data, size, 1) == XML_STATUS_ERROR) {
00645 MSG_EMERG("Parse error at line %d:\n%s\n",
00646 XML_GetCurrentLineNumber(parser),
00647 XML_ErrorString(XML_GetErrorCode(parser)));
00648 }
00649
00650 if (parsing_context->aborted == TRUE) {
00651 goto error;
00652 }
00653
00654 goto cleanup;
00655
00656 error:
00657
00658 if (configdata!=NULL) {
00659 free(configdata);
00660 configdata = NULL;
00661 }
00662
00663 cleanup:
00664
00665 if (parsing_context != NULL) {
00666
00667 free(parsing_context);
00668 parsing_context = NULL;
00669 }
00670
00671
00672 if (cwd != NULL) {
00673 g_free(cwd);
00674 cwd = NULL;
00675 }
00676
00677
00678 if (absfilepath != NULL) {
00679 g_free(absfilepath);
00680 absfilepath = NULL;
00681 }
00682
00683
00684 if (data != NULL) {
00685 free(data);
00686 data = NULL;
00687 }
00688
00689 #ifdef DEBUG
00690 if (configdata != NULL) {
00691 MSG_INF("----------- Configuration from '%s'", configdata->absfilepath);
00692 MSG_INF("mountpath='%s'", configdata->mountpath);
00693 MSG_INF("mountprefix='%s'", configdata->mountprefix);
00694 MSG_INF("user='%s'", configdata->user);
00695 MSG_INF("group='%s'", configdata->group);
00696 MSG_INF("wdir='%s'", configdata->wdir);
00697 MSG_INF("pidfile='%s'", configdata->pidfile);
00698 MSG_INF("filesystems");
00699 g_hash_table_foreach(configdata->filesystems, print_hm_entry, NULL);
00700 MSG_INF("dbus_reconnect='%d'", configdata->dbus_reconnect);
00701 MSG_INF("sleep_millis='%d'", configdata->sleep_millis);
00702 MSG_INF("loglevel='%d'", configdata->loglevel);
00703 MSG_INF("umount_on_exit='%s'",
00704 (configdata->umount_on_exit==UMOUNT_ON_EXIT_TRUE)?"true":(
00705 (configdata->umount_on_exit==UMOUNT_ON_EXIT_FALSE)?"false":"readonly"));
00706 MSG_INF("absfilepath='%s'", configdata->absfilepath);
00707 }
00708 #endif
00709
00710 return configdata;
00711 }
00712
00713
00714
00720 int
00721 mntd_volume_config_free(ConfigData **cfg)
00722 {
00723 ConfigData *configdata = *cfg;
00724
00725
00726 if (configdata == NULL) {
00727 return 0;
00728 }
00729
00730
00731 if (configdata->mountpath!=NULL) {
00732 free(configdata->mountpath);
00733 }
00734 if (configdata->user!=NULL) {
00735 free(configdata->user);
00736 }
00737 if (configdata->group!=NULL) {
00738 free(configdata->group);
00739 }
00740 if (configdata->wdir!=NULL) {
00741 free(configdata->wdir);
00742 }
00743 if (configdata->pidfile!=NULL) {
00744 free(configdata->pidfile);
00745 }
00746 if (configdata->filesystems!=NULL) {
00747 g_hash_table_destroy(configdata->filesystems);
00748 }
00749 if (configdata->absfilepath!=NULL) {
00750 free(configdata->absfilepath);
00751 }
00752
00753
00754 if (configdata != NULL) {
00755 memset(configdata, 0, sizeof(ConfigData));
00756 free(configdata);
00757 configdata = NULL;
00758 }
00759
00760
00761 *cfg = NULL;
00762
00763 return 0;
00764 }
00765
00766
00767
00777 void compare_filesystems(gpointer key, gpointer value, gpointer user_data);
00778 void compare_filesystems(gpointer key, gpointer value, gpointer user_data)
00779 {
00780 GHashTable *filesystems = (GHashTable *) user_data;
00781 gchar *o = NULL;
00782
00783 o = g_hash_table_lookup(filesystems, key);
00784 if (o != NULL) {
00785 if (strcmp(value, o) != 0) {
00786 MSG_NOTICE("<%s> changed from '%s' to '%s' (used for next mount).", key, value, o);
00787 }
00788 }
00789 }
00790
00791
00792
00799 int
00800 mntd_volume_config_reload(ConfigData **cfg, char *pidfile)
00801 {
00802 int res = 0;
00803 ConfigData *oldcfgdata = *cfg;
00804 ConfigData *newcfgdata = NULL;
00805
00806 g_assert(oldcfgdata!=NULL);
00807
00808 newcfgdata = mntd_volume_config_parse(oldcfgdata->absfilepath, pidfile);
00809 if (newcfgdata != NULL) {
00810
00811
00812 if (strcmp(oldcfgdata->user, newcfgdata->user) != 0) {
00813 MSG_WARNING("Changing <user> at runtime not allowed.");
00814 }
00815
00816
00817 if (strcmp(oldcfgdata->group, newcfgdata->group) != 0) {
00818 MSG_WARNING("Changing <group> at runtime not allowed.");
00819 }
00820
00821
00822 if (strcmp(oldcfgdata->wdir, newcfgdata->wdir) != 0) {
00823 MSG_WARNING("Changing <wdir> at runtime not allowed.");
00824 }
00825
00826
00827 if (strcmp(oldcfgdata->pidfile, newcfgdata->pidfile) != 0) {
00828 MSG_WARNING("Changing <pidfile> at runtime not allowed.");
00829 }
00830
00831
00832 if (strcmp(oldcfgdata->mountpath, newcfgdata->mountpath) != 0) {
00833 MSG_WARNING("Changing <mountpath> not allowed at runtime.");
00834 }
00835
00836
00837 if (oldcfgdata->dbus_reconnect != newcfgdata->dbus_reconnect) {
00838 MSG_NOTICE("<dbus_reconnect> changed from '%d' to '%d'.",
00839 oldcfgdata->dbus_reconnect, newcfgdata->dbus_reconnect);
00840 oldcfgdata->dbus_reconnect = newcfgdata->dbus_reconnect;
00841 }
00842
00843
00844 if (oldcfgdata->sleep_millis != newcfgdata->sleep_millis) {
00845 MSG_NOTICE("<dbus_reconnect sleep_millis=?> changed from '%d' to '%d'.",
00846 oldcfgdata->sleep_millis, newcfgdata->sleep_millis);
00847 oldcfgdata->sleep_millis = newcfgdata->sleep_millis;
00848 }
00849
00850
00851 if (oldcfgdata->loglevel != newcfgdata->loglevel) {
00852 #ifndef DEBUG
00853
00854 MSG_NOTICE("<loglevel> changed from '%d' to '%d'.",
00855 oldcfgdata->loglevel, newcfgdata->loglevel);
00856 oldcfgdata->loglevel = newcfgdata->loglevel;
00857 emInit(oldcfgdata->loglevel, EM_TYPE_SYSLOG, NULL, NULL, NULL, PACKAGE);
00858 #else
00859 MSG_WARNING("<loglevel> changed from '%d' to '%d' -> ignored while debugging.",
00860 oldcfgdata->loglevel, newcfgdata->loglevel);
00861 #endif
00862 }
00863
00864
00865 if (oldcfgdata->umount_on_exit != newcfgdata->umount_on_exit) {
00866 MSG_NOTICE("<umount_on_exit> changed from '%d' to '%d'.",
00867 oldcfgdata->umount_on_exit, newcfgdata->umount_on_exit);
00868 oldcfgdata->umount_on_exit = newcfgdata->umount_on_exit;
00869 }
00870
00871
00872 if (g_hash_table_size(oldcfgdata->filesystems) !=
00873 g_hash_table_size(newcfgdata->filesystems)) {
00874 MSG_NOTICE("<filesystems> changed from '%d' items to '%d' items (using new filesystems).",
00875 g_hash_table_size(oldcfgdata->filesystems),
00876 g_hash_table_size(newcfgdata->filesystems));
00877 } else {
00878
00879 g_hash_table_foreach(oldcfgdata->filesystems, compare_filesystems,
00880 newcfgdata->filesystems);
00881 }
00882
00883 g_hash_table_destroy(oldcfgdata->filesystems);
00884 oldcfgdata->filesystems = newcfgdata->filesystems;
00885
00886 } else {
00887 MSG_ERR("Out of memory.");
00888 goto error;
00889 }
00890
00891 goto cleanup;
00892
00893 error:
00894 res = -1;
00895
00896 cleanup:
00897 return res;
00898 }
00899
00900
00901