~ubuntu-branches/ubuntu/saucy/lvm2/saucy-proposed

« back to all changes in this revision

Viewing changes to daemons/clvmd/clvmd.c

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2012-08-14 14:35:57 UTC
  • mfrom: (3.1.25 sid)
  • Revision ID: package-import@ubuntu.com-20120814143557-93aill2tp3kf3o30
Tags: 2.02.95-4ubuntu1
* Merge from Debian unstable, remaining changes:
  - debian/patches/avoid-dev-block.patch: Prefer any other device name over
    names in /dev/block/ since lvm.conf won't handle this.
  - debian/rules:
    - copy .po file to .pot file for Rosetta (Ubuntu specific).
  - debian/{dmsetup,lvm2}-udeb.install:
    - install initramfs and udev hooks in udebs (Debian bug 504341).
  - auto-start VGs as their PVs are discovered (Ubuntu specific):
    - add debian/tree/lvm2/lib/udev/rules.d/85-lvm2.rules: use watershed plus
      the sledgehammer of vgscan/vgchange to turn on VGs as they come online.
    - debian/tree/lvm2/usr/share/initramfs-tools/scripts/hooks/lvm2:
      - add 85-lvm2.rules to the list of udev rules to copy.
      - depend on udev.
    - debian/control:
      - add versioned Depend on watershed in lvm2 for udev rules.
      - add Depends on watershed-udeb in lvm2-udeb for udev rules.
      - add versioned Depend/Breaks on udev in dmsetup for udev rules.
      - add Depend on initramfs-tools in dmsetup so system is not potentially
        rendered unbootable by out-of-order dpkg configuration.
    - debian/rules:
      - do not install local-top scripts since Ubuntu mounts root using udev.
      - do not install init scripts for lvm2, since udev starts LVM.
    - debian/lvm2.postinst: handle missing lvm2 init script.
    - debian/tree/dmsetup/lib/udev/rules.d/60-persistent-storage-dm.rules:
      watch dm devices for changes with inotify
  - add mountroot failure hooks to help fix bad boots (Debian bug 468115):
    - debian/tree/lvm2/usr/share/initramfs-tools/scripts/init-premount/lvm2
  - remaining changes to upstream event manager packages (Debian bug 514706):
    - debian/rules:
      - enable dmeventd during configure.
    - debian/dmeventd.{8,manpages}: install dmeventd files.
  - rename debian/clvm.defaults to debian/clvm.default so it is installed
    correctly.
  - debian/control: add dmsetup-udeb to libdevmapper1.02.1-udeb recommends.
  - debian/rules: make sure dmsetup and lvm2 initramfs-tools scripts are
    executable.  When the Ubuntu-specific ones are added with a patch,
    they may lose their executable bit.
  - Add and install clvmd resource agent
  - Add dependency on libudev-dev to libdevmapper-dev so that the .pc file
    works.
  - debian/{clvmd.ra,clvm.init}:
    - create /run/lvm if it doesn't exist.
  - debian/clvm.init:
    - exit 3 if not running on status action.
  - Call dh_installman so that our dmeventd manpage actually gets installed
  - Install the missing fsadm manpage.

 * libdevmapper-dev:
  - move .so symlinks and pkgconfig files to multiarched locations.
  - mark libdevmapper-dev M-A: same

 * libdevmapper-event1.02.1:
  - Add Breaks: dmeventd (<< 2.02.95-4ubuntu1) due to debian symbol rename

 * debian/lvm2.{preinst,postinst,postrm}:
  - Implement removal of obsolete /etc/init.d/lvm2 conffile, which
    should not have been re-introduced in Quantal.

 * Dropped Changes, included in Debian:
  - Mostly included packages for upstream event manager (Debian bug 514706).
  - debian/patches/rules-subdir.patch: removed as reordering will cause
    build failure with dmeventd.
  - debian/patches/libdm-event-static.patch: removed as other static libs
    aren't being built anymore either.
  - Update symbols for libdevmapper-event.
  - Update libdevmapper-event, dmeventd descriptions to match Debian
    boilerplate.

 * Disappeared Changes:
  - Don't install documentation in udebs. No diff found, but no docs are
    installed into udebs either.

 * Resurected Changes:
  - corrected dropping the wrong init script. Now clvm.init is shipped
    and lvm2.init is dropped in favor of udev rules as per original
    intention (LP: #1037033).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
3
 
 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
 
3
 * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
4
4
 *
5
5
 * This file is part of LVM2.
6
6
 *
49
49
#endif
50
50
 
51
51
#define MAX_RETRIES 4
 
52
#define MAX_MISSING_LEN 8000 /* Max supported clvmd message size ? */
52
53
 
53
54
#define ISLOCAL_CSID(c) (memcmp(c, our_csid, max_csid_len) == 0)
54
55
 
78
79
};
79
80
 
80
81
struct lvm_startup_params {
81
 
        char **argv;
 
82
        struct dm_hash_table *excl_uuid;
82
83
};
83
84
 
84
85
static debug_t debug = DEBUG_OFF;
85
86
static int foreground_mode = 0;
86
87
static pthread_t lvm_thread;
 
88
/* Stack size 128KiB for thread, must be bigger then DEFAULT_RESERVED_STACK */
 
89
static const size_t STACK_SIZE = 128 * 1024;
 
90
static pthread_attr_t stack_attr;
87
91
static pthread_mutex_t lvm_thread_mutex;
88
92
static pthread_cond_t lvm_thread_cond;
89
 
static pthread_mutex_t lvm_start_mutex;
 
93
static pthread_barrier_t lvm_start_barrier;
90
94
static struct dm_list lvm_cmd_head;
91
95
static volatile sig_atomic_t quit = 0;
92
96
static volatile sig_atomic_t reread_config = 0;
149
153
                "   -h       Show this help information\n"
150
154
                "   -d[n]    Set debug logging (0:none, 1:stderr (implies -f option), 2:syslog)\n"
151
155
                "   -f       Don't fork, run in the foreground\n"
 
156
                "   -E<lockuuid> Take this lock uuid as exclusively locked resource (for restart)\n"
152
157
                "   -R       Tell all running clvmds in the cluster to reload their device cache\n"
153
158
                "   -S       Restart clvmd, preserving exclusive locks\n"
154
159
                "   -C       Sets debug level (from -d) on all clvmd instances clusterwide\n"
194
199
        if (*fd >= 0) {
195
200
                int to_close = *fd;
196
201
                *fd = -1;
197
 
                close(to_close);
 
202
                if (close(to_close))
 
203
                        log_sys_error("close", ""); /* path */
198
204
        }
199
205
}
200
206
 
299
305
                break;
300
306
        }
301
307
 
302
 
        sprintf(buf, "%s (0x%x)", command, cmdl);
 
308
        snprintf(buf, sizeof(buf), "%s (0x%x)", command, cmdl);
303
309
 
304
310
        return buf;
305
311
}
331
337
{
332
338
        int local_sock;
333
339
        struct local_client *newfd, *delfd;
334
 
        struct utsname nodeinfo;
335
340
        struct lvm_startup_params lvm_params;
336
341
        int opt;
337
342
        int cmd_timeout = DEFAULT_CMD_TIMEOUT;
338
343
        int start_timeout = 0;
339
344
        if_type_t cluster_iface = IF_AUTO;
340
345
        sigset_t ss;
341
 
        int debug_opt = 0;
 
346
        debug_t debug_opt = DEBUG_OFF;
342
347
        debug_t debug_arg = DEBUG_OFF;
343
348
        int clusterwide_opt = 0;
344
349
        mode_t old_mask;
 
350
        int ret = 1;
345
351
 
346
352
        struct option longopts[] = {
347
353
                { "help", 0, 0, 'h' },
348
354
                { NULL, 0, 0, 0 }
349
355
        };
350
356
 
 
357
        if (!(lvm_params.excl_uuid = dm_hash_create(128))) {
 
358
                fprintf(stderr, "Failed to allocate hash table\n");
 
359
                return 1;
 
360
        }
 
361
 
351
362
        /* Deal with command-line arguments */
352
363
        opterr = 0;
353
364
        optind = 0;
364
375
 
365
376
                case 'S':
366
377
                        check_permissions();
367
 
                        return restart_clvmd(clusterwide_opt)==1?0:1;
 
378
                        ret = (restart_clvmd(clusterwide_opt) == 1) ? 0 : 1;
 
379
                        goto out;
368
380
 
369
381
                case 'C':
370
382
                        clusterwide_opt = 1;
371
383
                        break;
372
384
 
373
385
                case 'd':
374
 
                        debug_opt = 1;
375
 
                        debug_arg = optarg ? atoi(optarg) : DEBUG_STDERR;
 
386
                        debug_opt = DEBUG_STDERR;
 
387
                        debug_arg = optarg ? (debug_t) atoi(optarg) : DEBUG_STDERR;
376
388
                        if (debug_arg == DEBUG_STDERR)
377
389
                                foreground_mode = 1;
378
390
                        break;
391
403
                case 'I':
392
404
                        cluster_iface = parse_cluster_interface(optarg);
393
405
                        break;
 
406
                case 'E':
 
407
                        if (!dm_hash_insert(lvm_params.excl_uuid, optarg, optarg)) {
 
408
                                fprintf(stderr, "Failed to allocate hash entry\n");
 
409
                                goto out;
 
410
                        }
 
411
                        break;
394
412
                case 'T':
395
413
                        start_timeout = atoi(optarg);
396
414
                        if (start_timeout <= 0) {
425
443
                perror("Cannot set LANG to C");
426
444
 
427
445
        /* Setting debug options on an existing clvmd */
428
 
        if (debug_opt && !check_local_clvmd())
 
446
        if (debug_opt && !check_local_clvmd()) {
 
447
                dm_hash_destroy(lvm_params.excl_uuid);
429
448
                return debug_clvmd(debug_arg, clusterwide_opt)==1?0:1;
 
449
        }
430
450
 
431
451
        clvmd_set_debug(debug_opt);
432
452
 
483
503
 
484
504
        /* Initialise the LVM thread variables */
485
505
        dm_list_init(&lvm_cmd_head);
 
506
        if (pthread_attr_init(&stack_attr) ||
 
507
            pthread_attr_setstacksize(&stack_attr, STACK_SIZE)) {
 
508
                log_sys_error("pthread_attr_init", "");
 
509
                exit(1);
 
510
        }
486
511
        pthread_mutex_init(&lvm_thread_mutex, NULL);
487
512
        pthread_cond_init(&lvm_thread_cond, NULL);
488
 
        pthread_mutex_init(&lvm_start_mutex, NULL);
 
513
        pthread_barrier_init(&lvm_start_barrier, NULL, 2);
489
514
        init_lvhash();
490
515
 
491
516
        /* Start the cluster interface */
537
562
        DEBUGLOG("Cluster ready, doing some more initialisation\n");
538
563
 
539
564
        /* Save our CSID */
540
 
        uname(&nodeinfo);
541
565
        clops->get_our_csid(our_csid);
542
566
 
543
567
        /* Initialise the FD list head */
564
588
        DEBUGLOG("starting LVM thread\n");
565
589
 
566
590
        /* Don't let anyone else to do work until we are started */
567
 
        pthread_mutex_lock(&lvm_start_mutex);
568
 
        lvm_params.argv = argv;
569
 
        pthread_create(&lvm_thread, NULL, lvm_thread_fn, &lvm_params);
 
591
        pthread_create(&lvm_thread, &stack_attr, lvm_thread_fn, &lvm_params);
 
592
 
 
593
        /* Don't start until the LVM thread is ready */
 
594
        pthread_barrier_wait(&lvm_start_barrier);
570
595
 
571
596
        /* Tell the rest of the cluster our version number */
572
597
        if (clops->cluster_init_completed)
603
628
                free(delfd);
604
629
        }
605
630
 
606
 
        return 0;
 
631
        ret = 0;
 
632
out:
 
633
        dm_hash_destroy(lvm_params.excl_uuid);
 
634
 
 
635
        return ret;
607
636
}
608
637
 
609
638
/* Called when the cluster layer has completed initialisation.
640
669
        if (client_fd >= 0) {
641
670
                newfd = malloc(sizeof(struct local_client));
642
671
                if (!newfd) {
643
 
                        close(client_fd);
 
672
                        if (close(client_fd))
 
673
                                log_sys_error("close", "socket");
644
674
                        return 1;
645
675
                }
646
676
 
716
746
                         status, sock_client);
717
747
                /* But has the client gone away ?? */
718
748
                if (sock_client == NULL) {
719
 
                        DEBUGLOG
720
 
                            ("Got PIPE response for dead client, ignoring it\n");
 
749
                        DEBUGLOG("Got PIPE response for dead client, ignoring it\n");
721
750
                } else {
722
751
                        /* If error then just return that code */
723
752
                        if (status)
724
753
                                send_local_reply(sock_client, status,
725
754
                                                 sock_client->fd);
726
755
                        else {
727
 
                                if (sock_client->bits.localsock.state ==
728
 
                                    POST_COMMAND) {
 
756
                                /* FIXME: closer inspect this code since state is write thread protected */
 
757
                                pthread_mutex_lock(&sock_client->bits.localsock.mutex);
 
758
                                if (sock_client->bits.localsock.state == POST_COMMAND) {
 
759
                                        pthread_mutex_unlock(&sock_client->bits.localsock.mutex);
729
760
                                        send_local_reply(sock_client, 0,
730
761
                                                         sock_client->fd);
731
 
                                } else  // PRE_COMMAND finished.
732
 
                                {
733
 
                                        if (
734
 
                                            (status =
735
 
                                             distribute_command(sock_client)) !=
736
 
                                            0) send_local_reply(sock_client,
737
 
                                                                EFBIG,
738
 
                                                                sock_client->
739
 
                                                                fd);
 
762
                                } else {
 
763
                                        /* PRE_COMMAND finished. */
 
764
                                        pthread_mutex_unlock(&sock_client->bits.localsock.mutex);
 
765
                                        if ((status = distribute_command(sock_client)))
 
766
                                                send_local_reply(sock_client, EFBIG,
 
767
                                                                 sock_client->fd);
740
768
                                }
741
769
                        }
742
770
                }
1024
1052
                exit(2);
1025
1053
 
1026
1054
        case 0:         /* Child */
1027
 
                close(child_pipe[0]);
 
1055
                (void) close(child_pipe[0]);
1028
1056
                break;
1029
1057
 
1030
1058
        default:       /* Parent */
1031
 
                close(child_pipe[1]);
 
1059
                (void) close(child_pipe[1]);
1032
1060
                wait_for_child(child_pipe[0], timeout);
1033
1061
        }
1034
1062
 
1059
1087
        int len;
1060
1088
        int argslen;
1061
1089
        int missing_len;
1062
 
        char buffer[PIPE_BUF];
 
1090
        char buffer[PIPE_BUF + 1];
1063
1091
 
1064
 
        len = read(thisfd->fd, buffer, sizeof(buffer));
 
1092
        len = read(thisfd->fd, buffer, sizeof(buffer) - 1);
1065
1093
        if (len == -1 && errno == EINTR)
1066
1094
                return 1;
1067
1095
 
1112
1140
                                struct local_client *lastfd = NULL;
1113
1141
                                struct local_client *free_fd = NULL;
1114
1142
 
1115
 
                                close(thisfd->bits.localsock.pipe_client->fd);  /* Close pipe */
1116
 
                                close(thisfd->bits.localsock.pipe);
 
1143
                                (void) close(thisfd->bits.localsock.pipe_client->fd);   /* Close pipe */
 
1144
                                (void) close(thisfd->bits.localsock.pipe);
1117
1145
 
1118
1146
                                /* Remove pipe client */
1119
1147
                                for (newfd = &local_client_head; newfd != NULL;
1151
1179
                struct clvm_header *inheader;
1152
1180
                int status;
1153
1181
 
 
1182
                buffer[len] = 0; /* Ensure \0 terminated */
1154
1183
                inheader = (struct clvm_header *) buffer;
1155
1184
 
1156
1185
                /* Fill in the client ID */
1158
1187
 
1159
1188
                /* If we are already busy then return an error */
1160
1189
                if (thisfd->bits.localsock.in_progress) {
1161
 
                        struct clvm_header reply;
1162
 
                        reply.cmd = CLVMD_CMD_REPLY;
1163
 
                        reply.status = EBUSY;
1164
 
                        reply.arglen = 0;
1165
 
                        reply.flags = 0;
 
1190
                        struct clvm_header reply = {
 
1191
                                .cmd = CLVMD_CMD_REPLY,
 
1192
                                .status = EBUSY
 
1193
                        };
1166
1194
                        send_message(&reply, sizeof(reply), our_csid,
1167
1195
                                     thisfd->fd,
1168
1196
                                     "Error sending EBUSY reply to local user");
1169
1197
                        return len;
1170
1198
                }
1171
1199
 
1172
 
                /* Free any old buffer space */
1173
 
                free(thisfd->bits.localsock.cmd);
1174
 
 
1175
1200
                /* See if we have the whole message */
1176
1201
                argslen =
1177
1202
                    len - strlen(inheader->node) - sizeof(struct clvm_header);
1180
1205
                if (missing_len < 0)
1181
1206
                        missing_len = 0;
1182
1207
 
 
1208
                /* We need at least sizeof(struct clvm_header) bytes in buffer */
 
1209
                if (len < sizeof(struct clvm_header) || argslen < 0 ||
 
1210
                    missing_len > MAX_MISSING_LEN) {
 
1211
                        struct clvm_header reply = {
 
1212
                                .cmd = CLVMD_CMD_REPLY,
 
1213
                                .status = EINVAL
 
1214
                        };
 
1215
                        send_message(&reply, sizeof(reply), our_csid,
 
1216
                                     thisfd->fd,
 
1217
                                     "Error sending EINVAL reply to local user");
 
1218
                        return 0;
 
1219
                }
 
1220
 
 
1221
                /* Free any old buffer space */
 
1222
                free(thisfd->bits.localsock.cmd);
 
1223
 
1183
1224
                /* Save the message */
1184
1225
                thisfd->bits.localsock.cmd = malloc(len + missing_len);
1185
1226
 
1186
1227
                if (!thisfd->bits.localsock.cmd) {
1187
 
                        struct clvm_header reply;
1188
 
                        reply.cmd = CLVMD_CMD_REPLY;
1189
 
                        reply.status = ENOMEM;
1190
 
                        reply.arglen = 0;
1191
 
                        reply.flags = 0;
 
1228
                        struct clvm_header reply = {
 
1229
                                .cmd = CLVMD_CMD_REPLY,
 
1230
                                .status = ENOMEM
 
1231
                        };
1192
1232
                        send_message(&reply, sizeof(reply), our_csid,
1193
1233
                                     thisfd->fd,
1194
1234
                                     "Error sending ENOMEM reply to local user");
1203
1243
                        char *argptr =
1204
1244
                            inheader->node + strlen(inheader->node) + 1;
1205
1245
 
1206
 
                        while (missing_len > 0 && len >= 0) {
1207
 
                                DEBUGLOG
1208
 
                                    ("got %d bytes, need another %d (total %d)\n",
1209
 
                                     argslen, missing_len, inheader->arglen);
 
1246
                        while (missing_len > 0) {
 
1247
                                DEBUGLOG("got %d bytes, need another %d (total %d)\n",
 
1248
                                         argslen, missing_len, inheader->arglen);
1210
1249
                                len = read(thisfd->fd, argptr + argslen,
1211
1250
                                           missing_len);
1212
 
                                if (len >= 0) {
 
1251
                                if (len == -1 && errno == EINTR)
 
1252
                                        continue;
 
1253
                                if (len > 0) {
1213
1254
                                        missing_len -= len;
1214
1255
                                        argslen += len;
 
1256
                                } else {
 
1257
                                        /* EOF or error on socket */
 
1258
                                        DEBUGLOG("EOF on local socket\n");
 
1259
                                        free(thisfd->bits.localsock.cmd);
 
1260
                                        thisfd->bits.localsock.cmd = NULL;
 
1261
                                        return 0;
1215
1262
                                }
1216
1263
                        }
1217
1264
                }
1236
1283
                /* Check the node name for validity */
1237
1284
                if (inheader->node[0] && clops->csid_from_name(csid, inheader->node)) {
1238
1285
                        /* Error, node is not in the cluster */
1239
 
                        struct clvm_header reply;
 
1286
                        struct clvm_header reply = {
 
1287
                                .cmd = CLVMD_CMD_REPLY,
 
1288
                                .status = ENOENT
 
1289
                        };
 
1290
 
1240
1291
                        DEBUGLOG("Unknown node: '%s'\n", inheader->node);
1241
 
 
1242
 
                        reply.cmd = CLVMD_CMD_REPLY;
1243
 
                        reply.status = ENOENT;
1244
 
                        reply.flags = 0;
1245
 
                        reply.arglen = 0;
1246
1292
                        send_message(&reply, sizeof(reply), our_csid,
1247
1293
                                     thisfd->fd,
1248
1294
                                     "Error sending ENOENT reply to local user");
1264
1310
 
1265
1311
                /* Create a pipe and add the reading end to our FD list */
1266
1312
                if (pipe(comms_pipe)) {
1267
 
                        struct clvm_header reply;
 
1313
                        struct clvm_header reply = {
 
1314
                                .cmd = CLVMD_CMD_REPLY,
 
1315
                                .status = EBUSY
 
1316
                        };
 
1317
 
1268
1318
                        DEBUGLOG("creating pipe failed: %s\n", strerror(errno));
1269
 
                        reply.cmd = CLVMD_CMD_REPLY;
1270
 
                        reply.status = EBUSY;
1271
 
                        reply.arglen = 0;
1272
 
                        reply.flags = 0;
1273
1319
                        send_message(&reply, sizeof(reply), our_csid,
1274
1320
                                     thisfd->fd,
1275
1321
                                     "Error sending EBUSY reply to local user");
1278
1324
 
1279
1325
                newfd = malloc(sizeof(struct local_client));
1280
1326
                if (!newfd) {
1281
 
                        struct clvm_header reply;
1282
 
                        close(comms_pipe[0]);
1283
 
                        close(comms_pipe[1]);
1284
 
 
1285
 
                        reply.cmd = CLVMD_CMD_REPLY;
1286
 
                        reply.status = ENOMEM;
1287
 
                        reply.arglen = 0;
1288
 
                        reply.flags = 0;
 
1327
                        struct clvm_header reply = {
 
1328
                                .cmd = CLVMD_CMD_REPLY,
 
1329
                                .status = ENOMEM
 
1330
                        };
 
1331
 
 
1332
                        (void) close(comms_pipe[0]);
 
1333
                        (void) close(comms_pipe[1]);
 
1334
 
1289
1335
                        send_message(&reply, sizeof(reply), our_csid,
1290
1336
                                     thisfd->fd,
1291
1337
                                     "Error sending ENOMEM reply to local user");
1320
1366
                thisfd->bits.localsock.in_progress = TRUE;
1321
1367
                thisfd->bits.localsock.state = PRE_COMMAND;
1322
1368
                DEBUGLOG("Creating pre&post thread\n");
1323
 
                status = pthread_create(&thisfd->bits.localsock.threadid, NULL,
1324
 
                               pre_and_post_thread, thisfd);
 
1369
                status = pthread_create(&thisfd->bits.localsock.threadid,
 
1370
                                        &stack_attr, pre_and_post_thread, thisfd);
1325
1371
                DEBUGLOG("Created pre&post thread, state = %d\n", status);
1326
1372
        }
1327
1373
        return len;
1347
1393
        int len = thisfd->bits.localsock.cmd_len;
1348
1394
 
1349
1395
        thisfd->xid = global_xid++;
1350
 
        DEBUGLOG("distribute command: XID = %d\n", thisfd->xid);
 
1396
        DEBUGLOG("distribute command: XID = %d, flags=0x%x (%s%s)\n",
 
1397
                 thisfd->xid, inheader->flags,
 
1398
                (inheader->flags & CLVMD_FLAG_LOCAL) ? "LOCAL" : "",
 
1399
                (inheader->flags & CLVMD_FLAG_REMOTE) ? "REMOTE" : "");
1351
1400
 
1352
1401
        /* Forward it to other nodes in the cluster if needed */
1353
1402
        if (!(inheader->flags & CLVMD_FLAG_LOCAL)) {
1360
1409
                        thisfd->bits.localsock.in_progress = TRUE;
1361
1410
                        thisfd->bits.localsock.sent_out = TRUE;
1362
1411
 
1363
 
                        /* Do it here first */
 
1412
                        /*
 
1413
                         * Send to local node first, even if CLVMD_FLAG_REMOTE
 
1414
                         * is set so we still get a reply if this is the
 
1415
                         * only node.
 
1416
                         */
1364
1417
                        add_to_lvmqueue(thisfd, inheader, len, NULL);
1365
1418
 
1366
1419
                        DEBUGLOG("Sending message to all cluster nodes\n");
1471
1524
 
1472
1525
        if (replyargs != NULL) {
1473
1526
                /* Run the command */
1474
 
                status =
1475
 
                    do_command(NULL, msg, msglen, &replyargs, buflen,
1476
 
                               &replylen);
 
1527
                /* FIXME: usage of init_test() is unprotected */
 
1528
                status = do_command(NULL, msg, msglen, &replyargs,
 
1529
                                    buflen, &replylen);
1477
1530
        } else {
1478
1531
                status = ENOMEM;
1479
1532
        }
1590
1643
        DEBUGLOG("in sub thread: client = %p\n", client);
1591
1644
        pthread_mutex_lock(&client->bits.localsock.mutex);
1592
1645
 
1593
 
        /* Don't start until the LVM thread is ready */
1594
 
        pthread_mutex_lock(&lvm_start_mutex);
1595
 
        pthread_mutex_unlock(&lvm_start_mutex);
1596
 
        DEBUGLOG("Sub thread ready for work.\n");
1597
 
 
1598
1646
        /* Ignore SIGUSR1 (handled by master process) but enable
1599
1647
           SIGUSR2 (kills subthreads) */
1600
1648
        sigemptyset(&ss);
1608
1656
        /* Loop around doing PRE and POST functions until the client goes away */
1609
1657
        while (!client->bits.localsock.finished) {
1610
1658
                /* Execute the code */
 
1659
                /* FIXME: usage of init_test() is unprotected as in do_command() */
1611
1660
                status = do_pre_command(client);
1612
1661
 
1613
1662
                if (status)
1690
1739
        if (replybuf == NULL)
1691
1740
                return -1;
1692
1741
 
1693
 
        status = do_command(client, msg, msglen, &replybuf, buflen, &replylen);
 
1742
        /* If remote flag is set, just set a successful status code. */
 
1743
        if (msg->flags & CLVMD_FLAG_REMOTE)
 
1744
                status = 0;
 
1745
        else
 
1746
                /* FIXME: usage of init_test() is unprotected */
 
1747
                status = do_command(client, msg, msglen, &replybuf, buflen, &replylen);
1694
1748
 
1695
1749
        if (status)
1696
1750
                client->bits.localsock.all_success = 0;
1943
1997
 */
1944
1998
static void *lvm_thread_fn(void *arg)
1945
1999
{
1946
 
        struct dm_list *cmdl, *tmp;
1947
2000
        sigset_t ss;
1948
2001
        struct lvm_startup_params *lvm_params = arg;
 
2002
        struct lvm_thread_cmd *cmd;
1949
2003
 
1950
2004
        DEBUGLOG("LVM thread function started\n");
1951
2005
 
1956
2010
        pthread_sigmask(SIG_BLOCK, &ss, NULL);
1957
2011
 
1958
2012
        /* Initialise the interface to liblvm */
1959
 
        init_clvm(lvm_params->argv);
 
2013
        init_clvm(lvm_params->excl_uuid);
1960
2014
 
1961
2015
        /* Allow others to get moving */
1962
 
        pthread_mutex_unlock(&lvm_start_mutex);
 
2016
        pthread_barrier_wait(&lvm_start_barrier);
 
2017
        DEBUGLOG("Sub thread ready for work.\n");
1963
2018
 
1964
2019
        /* Now wait for some actual work */
 
2020
        pthread_mutex_lock(&lvm_thread_mutex);
 
2021
 
1965
2022
        while (!quit) {
1966
 
                DEBUGLOG("LVM thread waiting for work\n");
1967
 
 
1968
 
                pthread_mutex_lock(&lvm_thread_mutex);
1969
 
                if (dm_list_empty(&lvm_cmd_head))
 
2023
                if (dm_list_empty(&lvm_cmd_head)) {
 
2024
                        DEBUGLOG("LVM thread waiting for work\n");
1970
2025
                        pthread_cond_wait(&lvm_thread_cond, &lvm_thread_mutex);
1971
 
 
1972
 
                dm_list_iterate_safe(cmdl, tmp, &lvm_cmd_head) {
1973
 
                        struct lvm_thread_cmd *cmd;
1974
 
 
1975
 
                        cmd =
1976
 
                            dm_list_struct_base(cmdl, struct lvm_thread_cmd, list);
 
2026
                } else {
 
2027
                        cmd = dm_list_item(dm_list_first(&lvm_cmd_head),
 
2028
                                           struct lvm_thread_cmd);
1977
2029
                        dm_list_del(&cmd->list);
1978
2030
                        pthread_mutex_unlock(&lvm_thread_mutex);
1979
2031
 
1983
2035
 
1984
2036
                        pthread_mutex_lock(&lvm_thread_mutex);
1985
2037
                }
1986
 
                pthread_mutex_unlock(&lvm_thread_mutex);
1987
2038
        }
1988
2039
 
 
2040
        pthread_mutex_unlock(&lvm_thread_mutex);
 
2041
 
1989
2042
        pthread_exit(NULL);
1990
2043
}
1991
2044
 
2054
2107
                ret = -1;
2055
2108
        }
2056
2109
 
2057
 
        close(local_socket);
 
2110
        if (close(local_socket))
 
2111
                log_sys_error("close", "local socket");
 
2112
 
2058
2113
        return ret;
2059
2114
}
2060
2115
 
2061
2116
static void close_local_sock(int local_socket)
2062
2117
{
2063
2118
        if (local_socket != -1 && close(local_socket))
2064
 
                stack;
 
2119
                log_sys_error("close", CLVMD_SOCKNAME);
2065
2120
 
2066
2121
        if (CLVMD_SOCKNAME[0] != '\0' && unlink(CLVMD_SOCKNAME))
2067
2122
                stack;