source: trunk/packages/xen-3.1/xen-3.1/tools/blktap/drivers/blktapctrl.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 18.2 KB
Line 
1/*
2 * blktapctrl.c
3 *
4 * userspace controller for the blktap disks.
5 * As requests for new block devices arrive,
6 * the controller spawns off a separate process
7 * per-disk.
8 *
9 *
10 * Copyright (c) 2005 Julian Chesterfield and Andrew Warfield.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License version 2
14 * as published by the Free Software Foundation; or, when distributed
15 * separately from the Linux kernel or incorporated into other
16 * software packages, subject to the following license:
17 *
18 * Permission is hereby granted, free of charge, to any person obtaining a copy
19 * of this source file (the "Software"), to deal in the Software without
20 * restriction, including without limitation the rights to use, copy, modify,
21 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
22 * and to permit persons to whom the Software is furnished to do so, subject to
23 * the following conditions:
24 *
25 * The above copyright notice and this permission notice shall be included in
26 * all copies or substantial portions of the Software.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
34 * IN THE SOFTWARE.
35 */
36
37#include <stdio.h>
38#include <stdlib.h>
39#include <sys/mman.h>
40#include <sys/user.h>
41#include <err.h>
42#include <errno.h>
43#include <sys/types.h>
44#include <linux/types.h>
45#include <signal.h>
46#include <fcntl.h>
47#include <sys/poll.h>
48#include <sys/ioctl.h>
49#include <string.h>
50#include <unistd.h>
51#include <xs.h>
52#include <printf.h>
53#include <sys/time.h>
54#include <syslog.h>
55                                                                     
56#include "blktaplib.h"
57#include "blktapctrl.h"
58#include "tapdisk.h"
59
60#define PIDFILE "/var/run/blktapctrl.pid"
61
62#define NUM_POLL_FDS 2
63#define MSG_SIZE 4096
64#define MAX_TIMEOUT 10
65#define MAX_RAND_VAL 0xFFFF
66#define MAX_ATTEMPTS 10
67
68int run = 1;
69int max_timeout = MAX_TIMEOUT;
70int ctlfd = 0;
71
72int blktap_major;
73
74static int open_ctrl_socket(char *devname);
75static int write_msg(int fd, int msgtype, void *ptr, void *ptr2);
76static int read_msg(int fd, int msgtype, void *ptr);
77static driver_list_entry_t *active_disks[MAX_DISK_TYPES];
78
79static void init_driver_list(void)
80{
81        int i;
82
83        for (i = 0; i < MAX_DISK_TYPES; i++)
84                active_disks[i] = NULL;
85        return;
86}
87
88static void init_rng(void)
89{
90        static uint32_t seed;
91        struct timeval tv;
92
93        gettimeofday(&tv, NULL);
94        seed = tv.tv_usec;
95        srand48(seed);
96        return;
97}
98
99static void make_blktap_dev(char *devname, int major, int minor)
100{
101        struct stat st;
102       
103        if (lstat(devname, &st) != 0) {
104                /*Need to create device*/
105                if (mkdir(BLKTAP_DEV_DIR, 0755) == 0)
106                        DPRINTF("Created %s directory\n",BLKTAP_DEV_DIR);
107                if (mknod(devname, S_IFCHR|0600,
108                        makedev(major, minor)) == 0)
109                        DPRINTF("Created %s device\n",devname);
110        } else {
111                DPRINTF("%s device already exists\n",devname);
112                /* it already exists, but is it the same major number */
113                if (((st.st_rdev>>8) & 0xff) != major) {
114                        DPRINTF("%s has old major %d\n",
115                                devname,
116                                (unsigned int)((st.st_rdev >> 8) & 0xff));
117                        /* only try again if we succed in deleting it */
118                        if (!unlink(devname))
119                                make_blktap_dev(devname, major, minor);
120                }
121        }
122}
123
124static int get_new_dev(int *major, int *minor, blkif_t *blkif)
125{
126        domid_translate_t tr;
127        int ret;
128        char *devname;
129       
130        tr.domid = blkif->domid;
131        tr.busid = (unsigned short)blkif->be_id;
132        ret = ioctl(ctlfd, BLKTAP_IOCTL_NEWINTF, tr );
133       
134        if ( (ret <= 0)||(ret > MAX_TAP_DEV) ) {
135                DPRINTF("Incorrect Dev ID [%d]\n",ret);
136                return -1;
137        }
138       
139        *minor = ret;
140        *major = ioctl(ctlfd, BLKTAP_IOCTL_MAJOR, ret );
141        if (*major < 0) {
142                DPRINTF("Incorrect Major ID [%d]\n",*major);
143                return -1;
144        }
145
146        asprintf(&devname,"%s/%s%d",BLKTAP_DEV_DIR, BLKTAP_DEV_NAME, *minor);
147        make_blktap_dev(devname,*major,*minor); 
148        DPRINTF("Received device id %d and major %d, "
149                "sent domid %d and be_id %d\n",
150                *minor, *major, tr.domid, tr.busid);
151        return 0;
152}
153
154static int get_tapdisk_pid(blkif_t *blkif)
155{
156        int ret;
157
158        if ((ret = write_msg(blkif->fds[WRITE], CTLMSG_PID, blkif, NULL)) 
159            <= 0) {
160                DPRINTF("Write_msg failed - CTLMSG_PID(%d)\n", ret);
161                return -EINVAL;
162        }
163
164        if ((ret = read_msg(blkif->fds[READ], CTLMSG_PID_RSP, blkif))
165             <= 0) {
166                DPRINTF("Read_msg failure - CTLMSG_PID(%d)\n", ret);
167                return -EINVAL;
168        }       
169        return 1;
170}
171
172/* Look up the disk specified by path:
173 *   if found, dev points to the device string in the path
174 *             type is the tapdisk driver type id
175 *             blkif is the existing interface if this is a shared driver
176 *             and NULL otherwise.
177 *   return 0 on success, -1 on error.
178 */
179
180static int test_path(char *path, char **dev, int *type, blkif_t **blkif)
181{
182        char *ptr, handle[10];
183        int i, size, found = 0;
184
185        size = sizeof(dtypes)/sizeof(disk_info_t *);
186        *type = MAX_DISK_TYPES + 1;
187        *blkif = NULL;
188
189        if ( (ptr = strstr(path, ":"))!=NULL) {
190                memcpy(handle, path, (ptr - path));
191                *dev = ptr + 1;
192                ptr = handle + (ptr - path);
193                *ptr = '\0';
194                DPRINTF("Detected handle: [%s]\n",handle);
195
196                for (i = 0; i < size; i++) 
197                        if (strncmp(handle, dtypes[i]->handle, 
198                                    (ptr - path)) ==0) {
199                                found = 1;
200                                break;
201                        }
202
203                if (found) {
204                        *type = dtypes[i]->idnum;
205                       
206                        if (dtypes[i]->single_handler == 1) {
207                                /* Check whether tapdisk process
208                                   already exists */
209                                if (active_disks[dtypes[i]->idnum] == NULL) 
210                                        *blkif = NULL;
211                                else 
212                                        *blkif = active_disks[dtypes[i]
213                                                             ->idnum]->blkif;
214                        }
215                        return 0;
216                }
217        }
218
219        /* Fall-through case, we didn't find a disk driver. */
220        DPRINTF("Unknown blktap disk type [%s]!\n",handle);
221        *dev = NULL;
222        return -1;
223}
224
225
226static void add_disktype(blkif_t *blkif, int type)
227{
228        driver_list_entry_t *entry, **pprev;
229
230        if (type > MAX_DISK_TYPES)
231                return;
232
233        entry = malloc(sizeof(driver_list_entry_t));
234        entry->blkif = blkif;
235        entry->next  = NULL;
236
237        pprev = &active_disks[type];
238        while (*pprev != NULL)
239                pprev = &(*pprev)->next;
240
241        *pprev = entry;
242        entry->pprev = pprev;
243}
244
245static int del_disktype(blkif_t *blkif)
246{
247        driver_list_entry_t *entry, **pprev;
248        int type = blkif->drivertype, count = 0, close = 0;
249
250        if (type > MAX_DISK_TYPES)
251                return 1;
252
253        pprev = &active_disks[type];
254        while ((*pprev != NULL) && ((*pprev)->blkif != blkif))
255                pprev = &(*pprev)->next;
256
257        if ((entry = *pprev) == NULL) {
258                DPRINTF("DEL_DISKTYPE: No match\n");
259                return 1;
260        }
261
262        *pprev = entry->next;
263        if (entry->next)
264                entry->next->pprev = pprev;
265
266        DPRINTF("DEL_DISKTYPE: Freeing entry\n");
267        free(entry);
268
269        /* Caller should close() if no single controller, or list is empty. */
270        return (!dtypes[type]->single_handler || (active_disks[type] == NULL));
271}
272
273static int write_msg(int fd, int msgtype, void *ptr, void *ptr2)
274{
275        blkif_t *blkif;
276        blkif_info_t *blk;
277        msg_hdr_t *msg;
278        msg_newdev_t *msg_dev;
279        char *p, *buf, *path;
280        int msglen, len, ret;
281        fd_set writefds;
282        struct timeval timeout;
283        image_t *image, *img;
284        uint32_t seed;
285
286        blkif = (blkif_t *)ptr;
287        blk = blkif->info;
288        image = blkif->prv;
289        len = 0;
290
291        switch (msgtype)
292        {
293        case CTLMSG_PARAMS:
294                path = (char *)ptr2;
295                DPRINTF("Write_msg called: CTLMSG_PARAMS, sending [%s, %s]\n",
296                        blk->params, path);
297
298                msglen = sizeof(msg_hdr_t) + strlen(path) + 1;
299                buf = malloc(msglen);
300
301                /*Assign header fields*/
302                msg = (msg_hdr_t *)buf;
303                msg->type = CTLMSG_PARAMS;
304                msg->len = msglen;
305                msg->drivertype = blkif->drivertype;
306                msg->readonly = blkif->readonly;
307
308                gettimeofday(&timeout, NULL);
309                msg->cookie = blkif->cookie;
310                DPRINTF("Generated cookie, %d\n",blkif->cookie);
311
312                /*Copy blk->params to msg*/
313                p = buf + sizeof(msg_hdr_t);
314                memcpy(p, path, strlen(path) + 1);
315
316                break;
317
318        case CTLMSG_NEWDEV:
319                DPRINTF("Write_msg called: CTLMSG_NEWDEV\n");
320
321                msglen = sizeof(msg_hdr_t) + sizeof(msg_newdev_t);
322                buf = malloc(msglen);
323               
324                /*Assign header fields*/
325                msg = (msg_hdr_t *)buf;
326                msg->type = CTLMSG_NEWDEV;
327                msg->len = msglen;
328                msg->drivertype = blkif->drivertype;
329                msg->cookie = blkif->cookie;
330               
331                msg_dev = (msg_newdev_t *)(buf + sizeof(msg_hdr_t));
332                msg_dev->devnum = blkif->minor;
333                msg_dev->domid = blkif->domid;
334
335                break;
336
337        case CTLMSG_CLOSE:
338                DPRINTF("Write_msg called: CTLMSG_CLOSE\n");
339
340                msglen = sizeof(msg_hdr_t);
341                buf = malloc(msglen);
342               
343                /*Assign header fields*/
344                msg = (msg_hdr_t *)buf;
345                msg->type = CTLMSG_CLOSE;
346                msg->len = msglen;
347                msg->drivertype = blkif->drivertype;
348                msg->cookie = blkif->cookie;
349               
350                break;
351
352        case CTLMSG_PID:
353                DPRINTF("Write_msg called: CTLMSG_PID\n");
354
355                msglen = sizeof(msg_hdr_t);
356                buf = malloc(msglen);
357               
358                /*Assign header fields*/
359                msg = (msg_hdr_t *)buf;
360                msg->type = CTLMSG_PID;
361                msg->len = msglen;
362                msg->drivertype = blkif->drivertype;
363                msg->cookie = blkif->cookie;
364               
365                break;
366               
367        default:
368                return -1;
369        }
370
371        /*Now send the message*/
372        ret = 0;
373        FD_ZERO(&writefds);
374        FD_SET(fd,&writefds);
375        timeout.tv_sec = max_timeout; /*Wait for up to max_timeout seconds*/
376        timeout.tv_usec = 0;
377        if (select(fd+1, (fd_set *) 0, &writefds, 
378                  (fd_set *) 0, &timeout) > 0) {
379                len = write(fd, buf, msglen);
380                if (len == -1) DPRINTF("Write failed: (%d)\n",errno);
381        }
382        free(buf);
383
384        return len;
385}
386
387static int read_msg(int fd, int msgtype, void *ptr)
388{
389        blkif_t *blkif;
390        blkif_info_t *blk;
391        msg_hdr_t *msg;
392        msg_pid_t *msg_pid;
393        char *p, *buf;
394        int msglen = MSG_SIZE, len, ret;
395        fd_set readfds;
396        struct timeval timeout;
397        image_t *image, *img;
398
399
400        blkif = (blkif_t *)ptr;
401        blk = blkif->info;
402        image = blkif->prv;
403
404        buf = malloc(MSG_SIZE);
405
406        ret = 0;
407        FD_ZERO(&readfds);
408        FD_SET(fd,&readfds);
409        timeout.tv_sec = max_timeout; /*Wait for up to max_timeout seconds*/ 
410        timeout.tv_usec = 0;
411        if (select(fd+1, &readfds,  (fd_set *) 0,
412                  (fd_set *) 0, &timeout) > 0) {
413                ret = read(fd, buf, msglen);
414        }                       
415        if (ret > 0) {
416                msg = (msg_hdr_t *)buf;
417                switch (msg->type)
418                {
419                case CTLMSG_IMG:
420                        img = (image_t *)(buf + sizeof(msg_hdr_t));
421                        image->size = img->size;
422                        image->secsize = img->secsize;
423                        image->info = img->info;
424
425                        DPRINTF("Received CTLMSG_IMG: %llu, %lu, %u\n",
426                                image->size, image->secsize, image->info);
427                        if(msgtype != CTLMSG_IMG) ret = 0;
428                        break;
429                       
430                case CTLMSG_IMG_FAIL:
431                        DPRINTF("Received CTLMSG_IMG_FAIL, "
432                                "unable to open image\n");
433                        ret = 0;
434                        break;
435                               
436                case CTLMSG_NEWDEV_RSP:
437                        DPRINTF("Received CTLMSG_NEWDEV_RSP\n");
438                        if(msgtype != CTLMSG_NEWDEV_RSP) ret = 0;
439                        break;
440                       
441                case CTLMSG_NEWDEV_FAIL:
442                        DPRINTF("Received CTLMSG_NEWDEV_FAIL\n");
443                        ret = 0;
444                        break;
445                       
446                case CTLMSG_CLOSE_RSP:
447                        DPRINTF("Received CTLMSG_CLOSE_RSP\n");
448                        if (msgtype != CTLMSG_CLOSE_RSP) ret = 0;
449                        break;
450
451                case CTLMSG_PID_RSP:
452                        DPRINTF("Received CTLMSG_PID_RSP\n");
453                        if (msgtype != CTLMSG_PID_RSP) ret = 0;
454                        else {
455                                msg_pid = (msg_pid_t *)
456                                        (buf + sizeof(msg_hdr_t));
457                                blkif->tappid = msg_pid->pid;
458                                DPRINTF("\tPID: [%d]\n",blkif->tappid);
459                        }
460                        break;
461                default:
462                        DPRINTF("UNKNOWN MESSAGE TYPE RECEIVED\n");
463                        ret = 0;
464                        break;
465                }
466        } 
467       
468        free(buf);
469       
470        return ret;
471
472}
473
474int blktapctrl_new_blkif(blkif_t *blkif)
475{
476        blkif_info_t *blk;
477        int major, minor, fd_read, fd_write, type, new;
478        char *rdctldev, *wrctldev, *cmd, *ptr;
479        image_t *image;
480        blkif_t *exist = NULL;
481        static uint16_t next_cookie = 0;
482
483        DPRINTF("Received a poll for a new vbd\n");
484        if ( ((blk=blkif->info) != NULL) && (blk->params != NULL) ) {
485                if (get_new_dev(&major, &minor, blkif)<0)
486                        return -1;
487
488                if (test_path(blk->params, &ptr, &type, &exist) != 0) {
489                        DPRINTF("Error in blktap device string(%s).\n",
490                                blk->params);
491                        return -1;
492                }
493                blkif->drivertype = type;
494                blkif->cookie = next_cookie++;
495
496                if (!exist) {
497                        DPRINTF("Process does not exist:\n");
498                        asprintf(&rdctldev, 
499                                 "%s/tapctrlread%d", BLKTAP_CTRL_DIR, minor);
500                        blkif->fds[READ] = open_ctrl_socket(rdctldev);
501
502
503                        asprintf(&wrctldev, 
504                                 "%s/tapctrlwrite%d", BLKTAP_CTRL_DIR, minor);
505                        blkif->fds[WRITE] = open_ctrl_socket(wrctldev);
506                       
507                        if (blkif->fds[READ] == -1 || blkif->fds[WRITE] == -1) 
508                                goto fail;
509
510                        /*launch the new process*/
511                        asprintf(&cmd, "tapdisk %s %s", wrctldev, rdctldev);
512                        DPRINTF("Launching process, CMDLINE [%s]\n",cmd);
513                        if (system(cmd) == -1) {
514                                DPRINTF("Unable to fork, cmdline: [%s]\n",cmd);
515                                return -1;
516                        }
517
518                        free(rdctldev);
519                        free(wrctldev);
520                        free(cmd);
521                } else {
522                        DPRINTF("Process exists!\n");
523                        blkif->fds[READ] = exist->fds[READ];
524                        blkif->fds[WRITE] = exist->fds[WRITE];
525                }
526
527                add_disktype(blkif, type);
528                blkif->major = major;
529                blkif->minor = minor;
530
531                image = (image_t *)malloc(sizeof(image_t));
532                blkif->prv = (void *)image;
533                blkif->ops = &tapdisk_ops;
534
535                /*Retrieve the PID of the new process*/
536                if (get_tapdisk_pid(blkif) <= 0) {
537                        DPRINTF("Unable to contact disk process\n");
538                        goto fail;
539                }
540
541                /* Both of the following read and write calls will block up to
542                 * max_timeout val*/
543                if (write_msg(blkif->fds[WRITE], CTLMSG_PARAMS, blkif, ptr) 
544                    <= 0) {
545                        DPRINTF("Write_msg failed - CTLMSG_PARAMS\n");
546                        goto fail;
547                }
548
549                if (read_msg(blkif->fds[READ], CTLMSG_IMG, blkif) <= 0) {
550                        DPRINTF("Read_msg failure - CTLMSG_IMG\n");
551                        goto fail;
552                }
553
554        } else return -1;
555
556        return 0;
557fail:
558        ioctl(ctlfd, BLKTAP_IOCTL_FREEINTF, minor);
559        return -EINVAL;
560}
561
562int map_new_blktapctrl(blkif_t *blkif)
563{
564        DPRINTF("Received a poll for a new devmap\n");
565        if (write_msg(blkif->fds[WRITE], CTLMSG_NEWDEV, blkif, NULL) <= 0) {
566                DPRINTF("Write_msg failed - CTLMSG_NEWDEV\n");
567                return -EINVAL;
568        }
569
570        if (read_msg(blkif->fds[READ], CTLMSG_NEWDEV_RSP, blkif) <= 0) {
571                DPRINTF("Read_msg failed - CTLMSG_NEWDEV_RSP\n");
572                return -EINVAL;
573        }
574        DPRINTF("Exiting map_new_blktapctrl\n");
575
576        return blkif->minor - 1;
577}
578
579int unmap_blktapctrl(blkif_t *blkif)
580{
581        DPRINTF("Unmapping vbd\n");
582
583        if (write_msg(blkif->fds[WRITE], CTLMSG_CLOSE, blkif, NULL) <= 0) {
584                DPRINTF("Write_msg failed - CTLMSG_CLOSE\n");
585                return -EINVAL;
586        }
587
588        if (del_disktype(blkif)) {
589                close(blkif->fds[WRITE]);
590                close(blkif->fds[READ]);
591        }
592
593        return 0;
594}
595
596int open_ctrl_socket(char *devname)
597{
598        int ret;
599        int ipc_fd;
600        char *cmd;
601        fd_set socks;
602        struct timeval timeout;
603
604        if (mkdir(BLKTAP_CTRL_DIR, 0755) == 0)
605                DPRINTF("Created %s directory\n", BLKTAP_CTRL_DIR);
606        ret = mkfifo(devname,S_IRWXU|S_IRWXG|S_IRWXO);
607        if ( (ret != 0) && (errno != EEXIST) ) {
608                DPRINTF("ERROR: pipe failed (%d)\n", errno);
609                exit(0);
610        }
611
612        ipc_fd = open(devname,O_RDWR|O_NONBLOCK);
613
614        if (ipc_fd < 0) {
615                DPRINTF("FD open failed\n");
616                return -1;
617        }
618
619        return ipc_fd;
620}
621
622static void print_drivers(void)
623{
624        int i, size;
625
626        size = sizeof(dtypes)/sizeof(disk_info_t *);
627        DPRINTF("blktapctrl: v1.0.0\n");
628        for (i = 0; i < size; i++)
629                DPRINTF("Found driver: [%s]\n",dtypes[i]->name);
630} 
631
632static void write_pidfile(long pid)
633{
634        char buf[100];
635        int len;
636        int fd;
637        int flags;
638
639        fd = open(PIDFILE, O_RDWR | O_CREAT, 0600);
640        if (fd == -1) {
641                DPRINTF("Opening pid file failed (%d)\n", errno);
642                exit(1);
643        }
644
645        /* We exit silently if daemon already running. */
646        if (lockf(fd, F_TLOCK, 0) == -1)
647                exit(0);
648
649        /* Set FD_CLOEXEC, so that tapdisk doesn't get this file
650           descriptor. */
651        if ((flags = fcntl(fd, F_GETFD)) == -1) {
652                DPRINTF("F_GETFD failed (%d)\n", errno);
653                exit(1);
654        }
655        flags |= FD_CLOEXEC;
656        if (fcntl(fd, F_SETFD, flags) == -1) {
657                DPRINTF("F_SETFD failed (%d)\n", errno);
658                exit(1);
659        }
660
661        len = sprintf(buf, "%ld\n", pid);
662        if (write(fd, buf, len) != len) {
663                DPRINTF("Writing pid file failed (%d)\n", errno);
664                exit(1);
665        }
666}
667
668int main(int argc, char *argv[])
669{
670        char *devname;
671        tapdev_info_t *ctlinfo;
672        int tap_pfd, store_pfd, xs_fd, ret, timeout, pfd_count, count=0;
673        struct xs_handle *h;
674        struct pollfd  pfd[NUM_POLL_FDS];
675        pid_t process;
676        char buf[128];
677
678        __init_blkif();
679        snprintf(buf, sizeof(buf), "BLKTAPCTRL[%d]", getpid());
680        openlog(buf, LOG_CONS|LOG_ODELAY, LOG_DAEMON);
681        daemon(0,0);
682
683        print_drivers();
684        init_driver_list();
685        init_rng();
686
687        register_new_blkif_hook(blktapctrl_new_blkif);
688        register_new_devmap_hook(map_new_blktapctrl);
689        register_new_unmap_hook(unmap_blktapctrl);
690
691        /* Attach to blktap0 */
692        asprintf(&devname,"%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME);
693        if ((ret = xc_find_device_number("blktap0")) < 0)
694                goto open_failed;
695        blktap_major = major(ret);
696        make_blktap_dev(devname,blktap_major,0);
697        ctlfd = open(devname, O_RDWR);
698        if (ctlfd == -1) {
699                DPRINTF("blktap0 open failed\n");
700                goto open_failed;
701        }
702
703
704 retry:
705        /* Set up store connection and watch. */
706        h = xs_daemon_open();
707        if (h == NULL) {
708                DPRINTF("xs_daemon_open failed -- "
709                        "is xenstore running?\n");
710                if (count < MAX_ATTEMPTS) {
711                        count++;
712                        sleep(2);
713                        goto retry;
714                } else goto open_failed;
715        }
716       
717        ret = setup_probe_watch(h);
718        if (ret != 0) {
719                DPRINTF("Failed adding device probewatch\n");
720                xs_daemon_close(h);
721                goto open_failed;
722        }
723
724        ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
725
726        process = getpid();
727        write_pidfile(process);
728        ret = ioctl(ctlfd, BLKTAP_IOCTL_SENDPID, process );
729
730        /*Static pollhooks*/
731        pfd_count = 0;
732        tap_pfd = pfd_count++;
733        pfd[tap_pfd].fd = ctlfd;
734        pfd[tap_pfd].events = POLLIN;
735       
736        store_pfd = pfd_count++;
737        pfd[store_pfd].fd = xs_fileno(h);
738        pfd[store_pfd].events = POLLIN;
739
740        while (run) {
741                timeout = 1000; /*Milliseconds*/
742                ret = poll(pfd, pfd_count, timeout);
743
744                if (ret > 0) {
745                        if (pfd[store_pfd].revents) {
746                                ret = xs_fire_next_watch(h);
747                        }
748                }
749        }
750
751        xs_daemon_close(h);
752        ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_PASSTHROUGH );
753        close(ctlfd);
754        closelog();
755
756        return 0;
757       
758 open_failed:
759        DPRINTF("Unable to start blktapctrl\n");
760        closelog();
761        return -1;
762}
763
764/*
765 * Local variables:
766 *  c-file-style: "linux"
767 *  indent-tabs-mode: t
768 *  c-indent-level: 8
769 *  c-basic-offset: 8
770 *  tab-width: 8
771 * End:
772 */
Note: See TracBrowser for help on using the repository browser.