~csurbhi/ubuntu/natty/mountall/mountall-stop-timer

« back to all changes in this revision

Viewing changes to src/mountall.c

  • Committer: Bryce Harrington
  • Date: 2011-03-08 00:11:32 UTC
  • mfrom: (351.1.2 mountall)
  • Revision ID: bryce@canonical.com-20110308001132-sn8mzxypqnaggna9
Merge mountall.timeout

Show diffs side-by-side

added added

removed removed

Lines of Context:
76
76
#define BUILTIN_FSTAB   "/lib/init/fstab"
77
77
 
78
78
#define BOREDOM_TIMEOUT 3
 
79
#define ROOTDELAY 30
79
80
 
80
81
enum exit {
81
82
        EXIT_OK = 0,            /* Ok */
93
94
        TAG_SWAP,
94
95
        TAG_NOWAIT,
95
96
        TAG_SKIPPED,
 
97
        TAG_TIMEOUT,
96
98
} Tag;
97
99
 
98
100
typedef enum {
227
229
                              ply_boot_client_t *client);
228
230
 
229
231
void   usr1_handler          (void *data, NihSignal *signal);
 
232
int    set_dev_wait_time        (NihOption *option, const char *arg);
230
233
 
231
234
 
232
235
/**
249
252
size_t num_virtual_mounted = 0;
250
253
size_t num_swap = 0;
251
254
size_t num_swap_mounted = 0;
 
255
size_t num_timeout = 0;
 
256
size_t num_timeout_mounted = 0;
252
257
 
253
258
/**
254
259
 * newly_mounted:
355
360
 **/
356
361
static NihTimer *boredom_timer = NULL;
357
362
 
 
363
/**
 
364
 * device_ready_timer:
 
365
 *
 
366
 * Having waited over ROOTDELAY seconds for certain devices to get ready,
 
367
 * exit mountall and trigger the upstart jobs for bringing up the device
 
368
 **/
 
369
 
 
370
NihTimer *device_ready_timer = NULL;
358
371
 
359
372
/**
360
373
 * daemonise:
385
398
 **/
386
399
static int no_events = FALSE;
387
400
 
 
401
/**
 
402
 ** dev-wait-time
 
403
 **
 
404
 ** Set to ROOTDELAY if not set. 
 
405
 ** Legal values are between 1sec to 2147483647 seconds.
 
406
 **/
 
407
static int dev_wait_time = FALSE;
 
408
 
 
409
 
 
410
 
388
411
 
389
412
static void
390
413
dequote (char *str)
1178
1201
                        nih_info (_("%s is %s"), MOUNT_NAME (mnt), "local");
1179
1202
                        num_local++;
1180
1203
                        break;
 
1204
                case TAG_TIMEOUT:
 
1205
                        nih_info (_("%s is %s"), MOUNT_NAME (mnt), "local with timeout");
 
1206
                        num_local++;
 
1207
                        num_timeout++;
 
1208
                        break;
1181
1209
                case TAG_REMOTE:
1182
1210
                        nih_info (_("%s is %s"), MOUNT_NAME (mnt), "remote");
1183
1211
                        num_remote++;
1231
1259
                        }
1232
1260
                } else {
1233
1261
                        if (! has_option (mnt, "nobootwait", FALSE)) {
1234
 
                                tag = TAG_LOCAL;
 
1262
                                if ( has_option (mnt, "timeout", FALSE))
 
1263
                                {
 
1264
                                        tag = TAG_TIMEOUT; 
 
1265
                                }
 
1266
                                else
 
1267
                                        tag = TAG_LOCAL;
 
1268
        
1235
1269
                        } else {
1236
1270
                                tag = TAG_NOWAIT;
1237
1271
                        }
1254
1288
                        if ((dep->tag == TAG_LOCAL)
1255
1289
                            && (mnt->tag != TAG_REMOTE))
1256
1290
                                mnt->tag = TAG_LOCAL;
 
1291
                        if ((dep->tag == TAG_TIMEOUT)
 
1292
                            && (mnt->tag != TAG_REMOTE))
 
1293
                                mnt->tag = TAG_LOCAL;
1257
1294
                        if (dep->tag == TAG_REMOTE)
1258
1295
                                mnt->tag = TAG_REMOTE;
1259
1296
                }
1276
1313
                return;
1277
1314
        }
1278
1315
 
 
1316
        if ((tag == TAG_VIRTUAL)
 
1317
            && (mnt->tag == TAG_TIMEOUT)) {
 
1318
                nih_debug ("%s is not virtual, inherited local (with timeout)",
 
1319
                           MOUNT_NAME (mnt));
 
1320
                return;
 
1321
        }
 
1322
 
1279
1323
        if ((tag == TAG_LOCAL)
1280
1324
            && (mnt->tag == TAG_REMOTE)) {
1281
1325
                nih_debug ("%s is not local, inherited remote",
1282
1326
                           MOUNT_NAME (mnt));
1283
1327
        }
1284
1328
 
 
1329
        if ((tag == TAG_TIMEOUT)
 
1330
            && (mnt->tag == TAG_REMOTE)) {
 
1331
                nih_debug ("%s is not local (with timeout), inherited remote",
 
1332
                           MOUNT_NAME (mnt));
 
1333
        }
 
1334
 
1285
1335
        /* Set the tag, then if it's one we'd normally inherit, set it on
1286
1336
         * any mount point that depends on this one.
1287
1337
         */
1288
1338
        mnt->tag = tag;
1289
1339
 
 
1340
        /* TAG_TIMEOUT is TAG_LOCAL with a timeout. timeout cannot be
 
1341
         * inherited but local could be */
 
1342
        if(tag == TAG_TIMEOUT)
 
1343
                tag = TAG_LOCAL;
 
1344
 
1290
1345
        if ((tag == TAG_LOCAL)
1291
1346
            || (tag == TAG_REMOTE)) {
1292
1347
                NIH_LIST_FOREACH (mounts, iter) {
1386
1441
        case TAG_LOCAL:
1387
1442
                num_local_mounted++;
1388
1443
                break;
 
1444
        case TAG_TIMEOUT:
 
1445
                num_local_mounted++;
 
1446
                num_timeout_mounted++;
 
1447
                if (num_timeout_mounted == num_timeout) {
 
1448
                        nih_message(_("\n %s finished! "), "local_timeout");
 
1449
                        /* Stop the timeout waiting for device to get ready"
 
1450
                         */
 
1451
                        if (device_ready_timer) {
 
1452
                                nih_free (device_ready_timer);
 
1453
                                device_ready_timer = NULL;
 
1454
                        }
 
1455
                }
 
1456
                break;
1389
1457
        case TAG_REMOTE:
1390
1458
                num_remote_mounted++;
1391
1459
                break;
1422
1490
        case TAG_LOCAL:
1423
1491
                num_local--;
1424
1492
                break;
 
1493
        case TAG_TIMEOUT:
 
1494
                num_local--;
 
1495
                num_timeout--;
 
1496
                break;
1425
1497
        case TAG_REMOTE:
1426
1498
                num_remote--;
1427
1499
                break;
1523
1595
 
1524
1596
 
1525
1597
void
 
1598
is_device_ready(void *    data, NihTimer *timer)
 
1599
{
 
1600
        device_ready_timer = NULL;
 
1601
        NIH_LIST_FOREACH (mounts, iter) {
 
1602
                Mount *mnt = (Mount *)iter;
 
1603
 
 
1604
                if (mnt->mounted)
 
1605
                        continue;
 
1606
                if (mnt->tag != TAG_TIMEOUT)
 
1607
                        continue;
 
1608
                /* If udev was not able to identify the expected device within
 
1609
                 * ROOTDELAY time, something is wrong */
 
1610
                if ((! mnt->ready)
 
1611
                    && (! mnt->nodev)
 
1612
                    && (! is_remote (mnt))
 
1613
                    && ((! strncmp (mnt->device, "/dev/", 5))
 
1614
                        || (! strncmp (mnt->device, "UUID=", 5))
 
1615
                        || (! strncmp (mnt->device, "LABEL=", 6))))
 
1616
                {
 
1617
                        nih_message("%s device not ready in ROOTDELAY sec", MOUNT_NAME (mnt));
 
1618
                        emit_event("device-not-ready", mnt);
 
1619
                        break;
 
1620
 
 
1621
                }
 
1622
 
 
1623
        }
 
1624
        
 
1625
}
 
1626
 
 
1627
void activate_timer()
 
1628
{
 
1629
        NIH_LIST_FOREACH (mounts, iter) {
 
1630
                Mount *mnt = (Mount *)iter;
 
1631
 
 
1632
                if (mnt->mounted)
 
1633
                        continue;
 
1634
                if (mnt->tag != TAG_TIMEOUT)
 
1635
                        continue;
 
1636
                /* If there's an underlying device that udev is going to deal with,
 
1637
                 * and it's not a virtual or remote filesystem, we wait for the udev
 
1638
                 * watcher to mark it ready within ROOTDELAY time.
 
1639
                 */
 
1640
                if ((! mnt->ready)
 
1641
                    && (! mnt->nodev)
 
1642
                    && (! is_remote (mnt))
 
1643
                    && ((! strncmp (mnt->device, "/dev/", 5))
 
1644
                        || (! strncmp (mnt->device, "UUID=", 5))
 
1645
                        || (! strncmp (mnt->device, "LABEL=", 6))))
 
1646
                {
 
1647
                        nih_message(_("Shall wait for device: %s for %d seconds, starting timer"), MOUNT_NAME (mnt), dev_wait_time);
 
1648
                        if(!dev_wait_time)
 
1649
                                dev_wait_time = ROOTDELAY;
 
1650
                        device_ready_timer = NIH_MUST (nih_timer_add_timeout (NULL, 
 
1651
                                                dev_wait_time, is_device_ready, NULL));
 
1652
                        break;
 
1653
 
 
1654
                }
 
1655
 
 
1656
        }
 
1657
 
 
1658
}
 
1659
 
 
1660
void
1526
1661
try_mounts (void)
1527
1662
{
1528
1663
        int all;
1841
1976
        }
1842
1977
 
1843
1978
        opts = cut_options (NULL, mnt, "showthrough", "optional",
1844
 
                            "bootwait", "nobootwait",
 
1979
                            "bootwait", "nobootwait", "timeout",
1845
1980
                            NULL);
1846
1981
        if (mnt->mounted && (! fake)) {
1847
1982
                char *tmp;
3196
3331
        }
3197
3332
}
3198
3333
 
 
3334
int set_dev_wait_time(NihOption *option, const char *arg)
 
3335
{
 
3336
        char * end_ptr;
 
3337
        dev_wait_time = strtol(arg, &end_ptr, 10);
 
3338
        int err = 0;
 
3339
        if(dev_wait_time <= 0) {
 
3340
                nih_error(_("\n Legal values of dev-wait-time lie between 1sec to 2147483647 sec"));
 
3341
                err = -1;
 
3342
        }
 
3343
        else if ((dev_wait_time == LONG_MIN) || (dev_wait_time == LONG_MAX)) {
 
3344
                nih_error(_("\n Legal values of dev-wait-time lie between 1sec to 2147483647 sec"));
 
3345
                err = -1;
 
3346
        }
 
3347
        else if (*end_ptr != '\0') {
 
3348
                nih_error(_("\n Legal values of dev-wait-time lie between 1sec to 2147483647 sec"));
 
3349
                err = -1;
 
3350
        }
 
3351
        return err;
 
3352
}
3199
3353
 
3200
3354
 
3201
3355
/**
3212
3366
          NULL, NULL, &fsck_fix, NULL },
3213
3367
        { 0, "no-events", N_("Do not emit events after mounting filesystems"),
3214
3368
          NULL, NULL, &no_events, NULL },
3215
 
 
 
3369
        { 0, "dev-wait-time", N_("In case of (bootwait,timeout): specify the time to wait for device to be detected"),
 
3370
          NULL, N_("value in seconds (Default is 30 seconds, Legal value between 1second to 2147483647 seconds)"), &dev_wait_time, set_dev_wait_time},
3216
3371
        NIH_OPTION_LAST
3217
3372
};
3218
3373
 
3396
3551
 
3397
3552
        /* See what's already mounted */
3398
3553
        mark_mounted ();
 
3554
        /* Activate the timer for a fs that is local, unmounted and waits for
 
3555
         * a device to be ready, before it can be mounted onto it. Timer on
 
3556
         * only for fs not marked with a "nobootwait=1" */
 
3557
        activate_timer();
3399
3558
 
3400
3559
        /* See what we can mount straight away, and then schedule the same
3401
3560
         * function to be run each time through the main loop.