Changeset f57ccb5 in mainline


Ignore:
Timestamp:
2015-08-11T16:03:59Z (9 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0bde8523
Parents:
1b23e33
Message:

Set partition type based on selected filesystem type.

Location:
uspace
Files:
1 added
17 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/uuid.c

    r1b23e33 rf57ccb5  
    3636#include <uuid.h>
    3737#include <stdlib.h>
     38#include <str.h>
    3839
    3940/** Generate UUID.
     
    8788}
    8889
     90/** Parse string UUID.
     91 *
     92 * If @a endptr is not NULL, it is set to point to the first character
     93 * following the UUID. If @a endptr is NULL, the string must not contain
     94 * any characters following the UUID, otherwise an error is returned.
     95 *
     96 * @param str    String beginning with UUID string representation
     97 * @param uuid   Place to store UUID
     98 * @param endptr Place to store pointer to end of UUID or @c NULL
     99 *
     100 * @return EOK on success or negative error code
     101 */
     102int uuid_parse(const char *str, uuid_t *uuid, const char **endptr)
     103{
     104        int rc;
     105        const char *eptr;
     106        uint32_t time_low;
     107        uint16_t time_mid;
     108        uint16_t time_ver;
     109        uint16_t clock;
     110        uint64_t node;
     111        int i;
     112
     113        rc = str_uint32_t(str, &eptr, 16, false, &time_low);
     114        if (rc != EOK || eptr != str + 8 || *eptr != '-')
     115                return EINVAL;
     116
     117        rc = str_uint16_t(str + 9, &eptr, 16, false, &time_mid);
     118        if (rc != EOK || eptr != str + 13 || *eptr != '-')
     119                return EINVAL;
     120
     121        rc = str_uint16_t(str + 14, &eptr, 16, false, &time_ver);
     122        if (rc != EOK || eptr != str + 18 || *eptr != '-')
     123                return EINVAL;
     124
     125        rc = str_uint16_t(str + 19, &eptr, 16, false, &clock);
     126        if (rc != EOK || eptr != str + 23 || *eptr != '-')
     127                return EINVAL;
     128
     129        rc = str_uint64_t(str + 24, &eptr, 16, false, &node);
     130        if (rc != EOK || eptr != str + 36 || *eptr != '\0')
     131                return EINVAL;
     132
     133        uuid->b[0] = time_low >> 24;
     134        uuid->b[1] = (time_low >> 16) & 0xff;
     135        uuid->b[2] = (time_low >> 8) & 0xff;
     136        uuid->b[3] = time_low & 0xff;
     137
     138        uuid->b[4] = time_mid >> 8;
     139        uuid->b[5] = time_mid & 0xff;
     140
     141        uuid->b[6] = time_ver >> 8;
     142        uuid->b[7] = time_ver & 0xff;
     143
     144        uuid->b[8] = clock >> 8;
     145        uuid->b[9] = clock & 0xff;
     146
     147        for (i = 0; i < 6; i++)
     148                uuid->b[10 + i] = (node >> 8 * (5 - i)) & 0xff;
     149
     150        if (endptr != NULL) {
     151                *endptr = str + 36;
     152        } else {
     153                if (*(str + 36) != '\0')
     154                        return EINVAL;
     155        }
     156
     157        return EOK;
     158}
     159
     160/** Format UUID into string representation.
     161 *
     162 * @param uuid UUID
     163 * @param rstr Place to store pointer to newly allocated string
     164 *
     165 * @return EOK on success, ENOMEM if out of memory
     166 */
     167int uuid_format(uuid_t *uuid, char **rstr)
     168{
     169        return ENOTSUP;
     170}
     171
     172
    89173/** @}
    90174 */
  • uspace/lib/c/generic/vbd.c

    r1b23e33 rf57ccb5  
    330330}
    331331
     332/** Suggest partition type based on partition content.
     333 *
     334 * @param vbd   Virtual Block Device
     335 * @param disk  Disk on which the partition will be created
     336 * @param pcnt  Partition content
     337 * @param ptype Place to store suggested partition type
     338 *
     339 * @return EOK on success or negative error code
     340 */
     341int vbd_suggest_ptype(vbd_t *vbd, service_id_t disk, label_pcnt_t pcnt,
     342    label_ptype_t *ptype)
     343{
     344        async_exch_t *exch;
     345        sysarg_t retval;
     346        ipc_call_t answer;
     347
     348        exch = async_exchange_begin(vbd->sess);
     349        aid_t req = async_send_2(exch, VBD_SUGGEST_PTYPE, disk, pcnt, &answer);
     350        int rc = async_data_read_start(exch, ptype, sizeof(label_ptype_t));
     351        async_exchange_end(exch);
     352
     353        if (rc != EOK) {
     354                async_forget(req);
     355                return EIO;
     356        }
     357
     358        async_wait_for(req, &retval);
     359        if (retval != EOK)
     360                return EIO;
     361
     362        return EOK;
     363}
     364
     365
    332366/** @}
    333367 */
  • uspace/lib/c/include/ipc/vbd.h

    r1b23e33 rf57ccb5  
    4646        VBD_PART_CREATE,
    4747        VBD_PART_DELETE,
     48        VBD_SUGGEST_PTYPE
    4849} vbd_request_t;
    4950
  • uspace/lib/c/include/types/label.h

    r1b23e33 rf57ccb5  
    3636#define LIBC_TYPES_LABEL_H_
    3737
     38#include <types/uuid.h>
     39
    3840/** Disk contents */
    3941typedef enum {
     
    7274        /** Label supports extended (and logical) partitions */
    7375        lf_ext_supp = 0x1,
     76        /** Partition type is in UUID format (otherwise in small number format) */
     77        lf_ptype_uuid = 0x2,
    7478        /** Currently it is possible to create a primary partition */
    75         lf_can_create_pri = 0x2,
     79        lf_can_create_pri = 0x4,
    7680        /** Currently it is possible to create an extended partition */
    77         lf_can_create_ext = 0x4,
     81        lf_can_create_ext = 0x8,
    7882        /** Currrently it is possible to create a logical partition */
    79         lf_can_create_log = 0x8
     83        lf_can_create_log = 0x10
    8084} label_flags_t;
     85
     86/** Partition type format */
     87typedef enum {
     88        /** Small number */
     89        lptf_num,
     90        /** UUID */
     91        lptf_uuid
     92} label_pt_fmt;
     93
     94/** Partition type */
     95typedef struct {
     96        /** Type format */
     97        label_pt_fmt fmt;
     98        /** Depending on @c fmt */
     99        union {
     100                /* Small number */
     101                uint8_t num;
     102                /** UUID */
     103                uuid_t uuid;
     104        } t;
     105} label_ptype_t;
     106
     107/** Partition content (used to get partition type suggestion) */
     108typedef enum {
     109        /** ExFAT */
     110        lpc_exfat,
     111        /** Ext4 */
     112        lpc_ext4,
     113        /** FAT12 or FAT16 */
     114        lpc_fat12_16,
     115        /** FAT32 */
     116        lpc_fat32,
     117        /** Minix file system */
     118        lpc_minix
     119} label_pcnt_t;
    81120
    82121#endif
  • uspace/lib/c/include/uuid.h

    r1b23e33 rf57ccb5  
    3737
    3838#include <stdint.h>
    39 
    40 enum {
    41         uuid_bytes = 16
    42 };
    43 
    44 /** Universally Unique Identifier */
    45 typedef struct {
    46         uint8_t b[uuid_bytes];
    47 } uuid_t;
     39#include <types/uuid.h>
    4840
    4941extern int uuid_generate(uuid_t *);
    5042extern void uuid_encode(uuid_t *, uint8_t *);
    5143extern void uuid_decode(uint8_t *, uuid_t *);
     44extern int uuid_parse(const char *, uuid_t *, const char **);
     45extern int uuid_format(uuid_t *, char **);
    5246
    5347#endif
  • uspace/lib/c/include/vbd.h

    r1b23e33 rf57ccb5  
    7474        label_pkind_t pkind;
    7575        /** Partition type */
    76         uint64_t ptype;
     76        label_ptype_t ptype;
    7777} vbd_part_spec_t;
    7878
     
    105105extern int vbd_part_delete(vbd_t *, vbd_part_id_t);
    106106extern void vbd_pspec_init(vbd_part_spec_t *);
     107extern int vbd_suggest_ptype(vbd_t *, service_id_t, label_pcnt_t,
     108    label_ptype_t *);
    107109
    108110#endif
  • uspace/lib/fdisk/src/fdisk.c

    r1b23e33 rf57ccb5  
    912912        aoff64_t fnblocks;
    913913        uint64_t block_size;
     914        label_pcnt_t pcnt;
    914915        unsigned i;
    915916        int index;
     
    932933        req_blocks = fdisk_ba_align_up(dev, req_blocks);
    933934
     935        pcnt = -1;
     936
     937        switch (pspec->fstype) {
     938        case fdfs_none:
     939        case fdfs_unknown:
     940                break;
     941        case fdfs_exfat:
     942                pcnt = lpc_exfat;
     943                break;
     944        case fdfs_fat:
     945                pcnt = lpc_fat32; /* XXX Detect FAT12/16 vs FAT32 */
     946                break;
     947        case fdfs_minix:
     948                pcnt = lpc_minix;
     949                break;
     950        case fdfs_ext4:
     951                pcnt = lpc_ext4;
     952                break;
     953        }
     954
     955        if (pcnt < 0)
     956                return EINVAL;
     957
    934958        printf("fdisk_part_spec_prepare() - switch\n");
    935959        switch (pspec->pkind) {
     
    952976                vpspec->nblocks = req_blocks;
    953977                vpspec->pkind = pspec->pkind;
    954                 if (pspec->pkind != lpk_extended)
    955                         vpspec->ptype = 42;
    956978                break;
    957979        case lpk_logical:
     
    967989                vpspec->nblocks = req_blocks;
    968990                vpspec->pkind = lpk_logical;
    969                 vpspec->ptype = 42;
    970                 break;
     991                vpspec->ptype.fmt = lptf_num;
     992                vpspec->ptype.t.num = 42;
     993                break;
     994        }
     995
     996        if (pspec->pkind != lpk_extended) {
     997                rc = vbd_suggest_ptype(dev->fdisk->vbd, dev->sid, pcnt,
     998                    &vpspec->ptype);
     999                if (rc != EOK)
     1000                        return EIO;
    9711001        }
    9721002
  • uspace/lib/label/include/label.h

    r1b23e33 rf57ccb5  
    5555extern int label_part_destroy(label_part_t *);
    5656extern void label_pspec_init(label_part_spec_t *);
     57extern int label_suggest_ptype(label_t *, label_pcnt_t, label_ptype_t *);
    5758
    5859#endif
  • uspace/lib/label/include/std/gpt.h

    r1b23e33 rf57ccb5  
    7777} __attribute__((packed)) gpt_entry_t;
    7878
     79/** Microsoft Basic Data Partition */
     80#define GPT_MS_BASIC_DATA "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"
     81/** Linux Filesystem Data */
     82#define GPT_LINUX_FS_DATA "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
     83/** I could not find any definition of Minix GUID partition type.
     84 * This is a randomly generated UUID */
     85#define GPT_MINIX_FAKE "8308e350-4e2d-46c7-8e3b-24b07e8ac674"
     86
    7987#endif
    8088
  • uspace/lib/label/include/std/mbr.h

    r1b23e33 rf57ccb5  
    5757};
    5858
    59 enum ptype {
     59enum mbr_ptype {
    6060        /** Unused partition entry */
    61         mbr_pt_unused   = 0x00,
     61        mbr_pt_unused       = 0x00,
    6262        /** Extended partition */
    63         mbr_pt_extended = 0x05
     63        mbr_pt_extended     = 0x05,
     64        /** Extended partition with LBA */
     65        mbr_pt_extended_lba = 0x0f,
     66        /** FAT16 with LBA */
     67        mbr_pt_fat16_lba    = 0x0e,
     68        /** FAT32 with LBA */
     69        mbr_pt_fat32_lba    = 0x0c,
     70        /** IFS, HPFS, NTFS, exFAT */
     71        mbr_pt_ms_advanced  = 0x07,
     72        /** Minix */
     73        mbr_pt_minix        = 0x81,
     74        /** Linux */
     75        mbr_pt_linux        = 0x83
    6476};
    6577
  • uspace/lib/label/include/types/liblabel.h

    r1b23e33 rf57ccb5  
    6161        int (*part_create)(label_t *, label_part_spec_t *, label_part_t **);
    6262        int (*part_destroy)(label_part_t *);
     63        int (*suggest_ptype)(label_t *, label_pcnt_t, label_ptype_t *);
    6364} label_ops_t;
    6465
     
    106107        aoff64_t nblocks;
    107108        /** Partition type */
    108         uint64_t ptype;
     109        label_ptype_t ptype;
    109110        /** Partition UUID */
    110111        uuid_t part_uuid;
     
    124125        label_pkind_t pkind;
    125126        /** Partition type */
    126         uint64_t ptype;
     127        label_ptype_t ptype;
    127128};
    128129
  • uspace/lib/label/src/gpt.c

    r1b23e33 rf57ccb5  
    5555static int gpt_part_create(label_t *, label_part_spec_t *, label_part_t **);
    5656static int gpt_part_destroy(label_part_t *);
     57static int gpt_suggest_ptype(label_t *, label_pcnt_t, label_ptype_t *);
    5758
    5859static void gpt_unused_pte(gpt_entry_t *);
     
    8081        .part_get_info = gpt_part_get_info,
    8182        .part_create = gpt_part_create,
    82         .part_destroy = gpt_part_destroy
     83        .part_destroy = gpt_part_destroy,
     84        .suggest_ptype = gpt_suggest_ptype
    8385};
    8486
     
    547549        linfo->dcnt = dc_label;
    548550        linfo->ltype = lt_gpt;
    549         linfo->flags = 0;
     551        linfo->flags = lf_ptype_uuid; /* Partition type is in UUID format */
    550552        if (gpt_can_create_pri(label))
    551553                linfo->flags = linfo->flags | lf_can_create_pri;
     
    607609        /* GPT only has primary partitions */
    608610        if (pspec->pkind != lpk_primary) {
     611                rc = EINVAL;
     612                goto error;
     613        }
     614
     615        /* Partition type must be in UUID format */
     616        if (pspec->ptype.fmt != lptf_uuid) {
    609617                rc = EINVAL;
    610618                goto error;
     
    663671}
    664672
     673static int gpt_suggest_ptype(label_t *label, label_pcnt_t pcnt,
     674    label_ptype_t *ptype)
     675{
     676        const char *ptid;
     677        int rc;
     678
     679        ptid = NULL;
     680
     681        switch (pcnt) {
     682        case lpc_fat12_16:
     683        case lpc_exfat:
     684        case lpc_fat32:
     685                ptid = GPT_MS_BASIC_DATA;
     686                break;
     687        case lpc_ext4:
     688                ptid = GPT_LINUX_FS_DATA;
     689                break;
     690        case lpc_minix:
     691                ptid = GPT_MINIX_FAKE;
     692                break;
     693        }
     694
     695        if (ptid == NULL)
     696                return EINVAL;
     697
     698        ptype->fmt = lptf_uuid;
     699        rc = uuid_parse(ptid, &ptype->t.uuid, NULL);
     700        assert(rc == EOK);
     701
     702        return EOK;
     703}
     704
    665705static void gpt_unused_pte(gpt_entry_t *pte)
    666706{
     
    677717
    678718        memset(pte, 0, sizeof(gpt_entry_t));
    679         pte->part_type[0] = 0x12;
     719        uuid_encode(&part->ptype.t.uuid, pte->part_type);
    680720        uuid_encode(&part->part_uuid, pte->part_id);
    681721        pte->start_lba = host2uint64_t_le(part->block0);
     
    713753        part->block0 = b0;
    714754        part->nblocks = b1 - b0 + 1;
     755        part->ptype.fmt = lptf_uuid;
     756        uuid_decode(pte->part_type, &part->ptype.t.uuid);
    715757        uuid_decode(pte->part_id, &part->part_uuid);
    716758
  • uspace/lib/label/src/label.c

    r1b23e33 rf57ccb5  
    133133}
    134134
     135int label_suggest_ptype(label_t *label, label_pcnt_t pcnt,
     136    label_ptype_t *ptype)
     137{
     138        return label->ops->suggest_ptype(label, pcnt, ptype);
     139}
     140
    135141/** @}
    136142 */
  • uspace/lib/label/src/mbr.c

    r1b23e33 rf57ccb5  
    5454static int mbr_part_create(label_t *, label_part_spec_t *, label_part_t **);
    5555static int mbr_part_destroy(label_part_t *);
     56static int mbr_suggest_ptype(label_t *, label_pcnt_t, label_ptype_t *);
    5657
    5758static void mbr_unused_pte(mbr_pte_t *);
     
    7778        .part_get_info = mbr_part_get_info,
    7879        .part_create = mbr_part_create,
    79         .part_destroy = mbr_part_destroy
     80        .part_destroy = mbr_part_destroy,
     81        .suggest_ptype = mbr_suggest_ptype
    8082};
    8183
     
    485487
    486488        log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_part_get_info: index=%d ptype=%d",
    487             (int)part->index, (int)part->ptype);
     489            (int)part->index, (int)part->ptype.t.num);
    488490        if (link_used(&part->llog))
    489491                pinfo->pkind = lpk_logical;
    490         else if (part->ptype == mbr_pt_extended)
     492        else if (part->ptype.t.num == mbr_pt_extended)
    491493                pinfo->pkind = lpk_extended;
    492494        else
     
    503505        int rc;
    504506
     507        if (pspec->ptype.fmt != lptf_num)
     508                return EINVAL;
     509
    505510        part = calloc(1, sizeof(label_part_t));
    506511        if (part == NULL)
     
    521526                break;
    522527        case lpk_extended:
    523                 part->ptype = mbr_pt_extended;
    524                 if (pspec->ptype != 0) {
     528                part->ptype.fmt = lptf_num;
     529                part->ptype.t.num = mbr_pt_extended;
     530                if (pspec->ptype.t.num != 0) {
    525531                        rc = EINVAL;
    526532                        goto error;
     
    705711}
    706712
     713static int mbr_suggest_ptype(label_t *label, label_pcnt_t pcnt,
     714    label_ptype_t *ptype)
     715{
     716        ptype->fmt = lptf_num;
     717        ptype->t.num = 0;
     718
     719        switch (pcnt) {
     720        case lpc_exfat:
     721                ptype->t.num = mbr_pt_ms_advanced;
     722                break;
     723        case lpc_ext4:
     724                ptype->t.num = mbr_pt_linux;
     725                break;
     726        case lpc_fat12_16:
     727                ptype->t.num = mbr_pt_fat16_lba;
     728                break;
     729        case lpc_fat32:
     730                ptype->t.num = mbr_pt_fat32_lba;
     731                break;
     732        case lpc_minix:
     733                ptype->t.num = mbr_pt_minix;
     734                break;
     735        }
     736
     737        if (ptype->t.num == 0)
     738                return EINVAL;
     739
     740        return EOK;
     741}
     742
     743
    707744static void mbr_unused_pte(mbr_pte_t *pte)
    708745{
     
    716753        if ((part->nblocks >> 32) != 0)
    717754                return EINVAL;
    718         if ((part->ptype >> 8) != 0)
     755        if ((part->ptype.t.num >> 8) != 0)
    719756                return EINVAL;
    720757
    721758        log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_part_to_pte: a0=%" PRIu64
    722759            " len=%" PRIu64 " ptype=%d", part->block0, part->nblocks,
    723             (int)part->ptype);
     760            (int)part->ptype.t.num);
    724761        memset(pte, 0, sizeof(mbr_pte_t));
    725         pte->ptype = part->ptype;
     762        pte->ptype = part->ptype.t.num;
    726763        pte->first_lba = host2uint32_t_le(part->block0);
    727764        pte->length = host2uint32_t_le(part->nblocks);
     
    746783                return ENOMEM;
    747784
    748         part->ptype = pte->ptype;
     785        part->ptype.fmt = lptf_num;
     786        part->ptype.t.num = pte->ptype;
    749787        part->index = index;
    750788        part->block0 = block0;
     
    786824        nlparts = list_count(&label->log_parts);
    787825
    788         part->ptype = pte->ptype;
     826        part->ptype.fmt = lptf_num;
     827        part->ptype.t.num = pte->ptype;
    789828        part->index = mbr_nprimary + 1 + nlparts;
    790829        part->block0 = block0;
     
    816855        if (pthis != NULL) {
    817856                memset(pthis, 0, sizeof(mbr_pte_t));
    818                 pthis->ptype = part->ptype;
     857                pthis->ptype = part->ptype.t.num;
    819858                pthis->first_lba = host2uint32_t_le(part->hdr_blocks);
    820859                pthis->length = host2uint32_t_le(part->nblocks);
  • uspace/srv/bd/vbd/disk.c

    r1b23e33 rf57ccb5  
    503503        rc = vbds_disk_by_svcid(sid, &disk);
    504504        if (rc != EOK) {
    505                 log_msg(LOG_DEFAULT, LVL_NOTE, "Partition %zu not found",
     505                log_msg(LOG_DEFAULT, LVL_NOTE, "Disk %zu not found",
    506506                    sid);
    507507                goto error;
     
    583583
    584584        return EOK;
     585}
     586
     587int vbds_suggest_ptype(service_id_t sid, label_pcnt_t pcnt,
     588    label_ptype_t *ptype)
     589{
     590        vbds_disk_t *disk;
     591        int rc;
     592
     593        rc = vbds_disk_by_svcid(sid, &disk);
     594        if (rc != EOK) {
     595                log_msg(LOG_DEFAULT, LVL_NOTE, "Disk %zu not found",
     596                    sid);
     597                goto error;
     598        }
     599
     600        rc = label_suggest_ptype(disk->label, pcnt, ptype);
     601        if (rc != EOK) {
     602                log_msg(LOG_DEFAULT, LVL_NOTE, "label_suggest_ptype() failed");
     603                goto error;
     604        }
     605
     606        return EOK;
     607error:
     608        return rc;
    585609}
    586610
  • uspace/srv/bd/vbd/disk.h

    r1b23e33 rf57ccb5  
    5252extern int vbds_part_create(service_id_t, vbd_part_spec_t *,vbds_part_id_t *);
    5353extern int vbds_part_delete(vbds_part_id_t);
     54extern int vbds_suggest_ptype(service_id_t, label_pcnt_t, label_ptype_t *);
    5455extern void vbds_bd_conn(ipc_callid_t, ipc_call_t *, void *);
    5556
  • uspace/srv/bd/vbd/vbd.c

    r1b23e33 rf57ccb5  
    208208}
    209209
    210 
    211210static void vbds_part_get_info_srv(ipc_callid_t iid, ipc_call_t *icall)
    212211{
     
    302301}
    303302
     303static void vbds_suggest_ptype_srv(ipc_callid_t iid, ipc_call_t *icall)
     304{
     305        service_id_t disk_sid;
     306        label_ptype_t ptype;
     307        label_pcnt_t pcnt;
     308        int rc;
     309
     310        log_msg(LOG_DEFAULT, LVL_NOTE, "vbds_suggest_ptype_srv()");
     311
     312        disk_sid = IPC_GET_ARG1(*icall);
     313        pcnt = IPC_GET_ARG2(*icall);
     314
     315        rc = vbds_suggest_ptype(disk_sid, pcnt, &ptype);
     316        if (rc != EOK) {
     317                async_answer_0(iid, rc);
     318                return;
     319        }
     320
     321        ipc_callid_t callid;
     322        size_t size;
     323        if (!async_data_read_receive(&callid, &size)) {
     324                async_answer_0(callid, EREFUSED);
     325                async_answer_0(iid, EREFUSED);
     326                return;
     327        }
     328
     329        if (size != sizeof(label_ptype_t)) {
     330                async_answer_0(callid, EINVAL);
     331                async_answer_0(iid, EINVAL);
     332                return;
     333        }
     334
     335        rc = async_data_read_finalize(callid, &ptype, sizeof(label_ptype_t));
     336        if (rc != EOK) {
     337                async_answer_0(callid, rc);
     338                async_answer_0(iid, rc);
     339                return;
     340        }
     341
     342        async_answer_0(iid, EOK);
     343}
     344
    304345static void vbds_ctl_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    305346{
     
    348389                        vbds_part_delete_srv(callid, &call);
    349390                        break;
     391                case VBD_SUGGEST_PTYPE:
     392                        vbds_suggest_ptype_srv(callid, &call);
     393                        break;
    350394                default:
    351395                        async_answer_0(callid, EINVAL);
Note: See TracChangeset for help on using the changeset viewer.